优化慢查询

时间:2013-05-16 18:07:47

标签: mysql

我不擅长优化SQL,但我需要这个查询尽可能快地运行。它将通过PHP脚本在大约40个不同的数据库上重复运行。 PHP然后按时间顺序对结果进行排序。

SELECT DATE_FORMAT(lastmoddate, '%a %b %D, %Y  %l:%i%p') as lastmod,
       count(*) as num_modified,
       (select count(*) from store.item) as totalitems,
       UNIX_TIMESTAMP(lastmoddate) as timestamp
FROM store.item
group by lastmoddate
HAVING lastmoddate = MAX(lastmoddate)
order by lastmoddate desc
limit 1;

解释

  • lastmoddate 是商品记录的最后修改日期
  • count(*)as num_modified 是上次更新时修改的项目数
  • 子查询获取表格中的总项目
  • UNIX_TIMESTAMP 可能是不必要的,但我稍后会用它在PHP中进行排序。此结果与其他数据库的结果合并,然后进行排序。

因此,最终目标是获取一个表,其中包含上次修改日期,在上次修改日期修改的项目数以及数据库中的总项目。

子查询可能会被删除,但它似乎不会对速度产生太大影响。其他结果是必需的。如果DATE_FORMAT或UNIX_TIMESTAMP很慢,它们可能会被删除,但它们会被PHP中的某些东西取代,这可能同样慢。 (就像我说的,我没有关于优化SQL的任何内容。我觉得只需要一个有效的查询就可以了。)

MySQL 5.5和PHP 5.3

2 个答案:

答案 0 :(得分:2)

您正在尝试获取有关最大lastmoddate行的信息。您的查询是按lastmoddate聚合所有数据,然后选择最后一行。

相反,首先进行过滤,然后进行聚合。您只在输出中获得一行,因此您甚至不需要group by子句。

方法是计算子查询中的最大最后修改日期和总项目。这已加入,因此可以过滤数据:

select DATE_FORMAT(i.lastmoddate, '%a %b %D, %Y  %l:%i%p') as lastmod,
       COUNT(*) as NumModified,
       const.totalitems,
       UNIX_TIMESTAMP(i.lastmoddate) as timestamp
from store.item i cross join
     (select max(lastmoddate) as maxlastmoddate, count(*) as totalitems
     ) const
where i.lastmoddate = const.maxlastmoddate;

store.item(lastmoddate)上的索引会进一步提升您的表现。

答案 1 :(得分:1)

您可以做的一件事是选择count(*)一次并将其作为子查询删除。把它放在循环之外,执行40次。

你需要有条款吗?没有它你会得到相同的结果吗?我认为可以将其放入where子句

WHERE lastmoddate = (select max(lastmoddate) from store.item i2)

确保您在lastmoddate上有索引。