jackyrong

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
   之前有个项目,已经充分用MYSQL的调优调了,速度感觉还可以.但发现索引没用上.于是调整之.

    首先,数据库中有date字段,是int类型的,入库时用php的time()入库的,现在的需求是
要求1天之内的记录,我们来看具体的写法,先看原来的
    $query = "select * from record where del<>0 and to_days(FROM_UNIXTIME(date, '%Y-%m-%d %H:%i:%S'))>=to_days(curdate())-1 order by date desc";
这里to_days() 是把时间转成unix的时间,注意,这个表达式用explain看过,用不到索引,主要是由于表达式的左右都有计算.
  再查了资料,其中有例子讲到:
     WHERE TO_DAYS(date_col) - TO_DAYS(CURDATE()) < cutoff
WHERE TO_DAYS(date_col) < cutoff + TO_DAYS(CURDATE())
WHERE date_col < DATE_ADD(CURDATE(), INTERVAL cutoff DAY)

  对于第一行,不会用到索引,因为每个数据行都必须检索以计算出TO_DAYS(date_col)的值。第二行要好一些。Cutoff和TO_DAYS(CURDATE())都是常量,因此在处理查询之前,比较表达式的右边可以被优化器一次性计算出来,而不需要每个数据行都计算一次。但是date_col列仍然出现在函数调用中,它阻止了索引的使用。第三行是这几个中最好的。同样,在执行查询之前,比较表达式的右边可以作为常量一次性计算出来,但是现在它的值是一个日期。这个值可以直接与date_col值进行比较,再也不需要转换成天数了。在这种情况下,会使用索引。

    但是,由于我们这个例子里,是unix时间的,因此有很大不同,想法是表达式的左边和右边都是单一量的比较,这样就肯定用到索引了,
所以一开始打算这样用
     

$time=date("Y/m/d",time()-24*60*60);


$date_time_array=getdate($time);
$hours=$date_time_array[ "hours"];
$minutes=$date_time_array["minutes"];
$seconds=$date_time_array[ "seconds"];
$month=$date_time_array["mon"];
$day=$date_time_array["mday"];
$year=$date_time_array["year"];
// 用mktime()函数重新产生Unix时间戳值
$timestamp = mktime($hours ,$minutes, $seconds,$month ,$day,$year);
echo $timestamp;

    这里实际上就是求出昨天的时间,然后将其转为unix时间,注意我们用了mktime函数.
最后在SQL里,嘿,索引用到了
    $query = "select * from record where del<>0 and date>=".$timestamp." order by date desc";
   但发现,和原来的对比,不能显示昨天0:00后的记录,查了下原因,发现了
原来$time=date("Y/m/d",time()-24*60*60);
  只是根据现在的时间,把时间减去一天,比如现在的时间是18:00,就求出昨天18:00的,不符合要求,
改的话很简单,只需要加上
   


$time=strtotime($time."00:00:00");


$date_time_array=getdate($time);

就可以了,强制是求出昨天0:00的时候的unix时间,再进行比较
结论:通过比较,时间缩短了差不多一半,可见索引的重要性!
   

 

 

posted on 2008-06-22 18:58  jackyrong的世界  阅读(563)  评论(0编辑  收藏  举报