我不擅长优化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;
解释
因此,最终目标是获取一个表,其中包含上次修改日期,在上次修改日期修改的项目数以及数据库中的总项目。
子查询可能会被删除,但它似乎不会对速度产生太大影响。其他结果是必需的。如果DATE_FORMAT或UNIX_TIMESTAMP很慢,它们可能会被删除,但它们会被PHP中的某些东西取代,这可能同样慢。 (就像我说的,我没有关于优化SQL的任何内容。我觉得只需要一个有效的查询就可以了。)
MySQL 5.5和PHP 5.3
答案 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上有索引。