我想知道为什么第一个查询比第二个查询快得多。它在约500k记录的表上运行。
SELECT date FROM `log` WHERE `action` = 'SOMETHING' and token = 167 ORDER BY id DESC LIMIT 1;
-- 0.0003 sec
SELECT max(date) FROM `log` WHERE `action` = 'SOMETHING' and token = 167;
-- 0.0023 sec
我的猜测是您没有索引日期,但是在ID上有索引(主键)?
如果ID是主要键,则可以对数据进行排序以更快地返回结果。这是因为即使您的查询仅返回日期列,也要按ID订购行,该行被索引,允许非常快地订购500K行。
要返回最大日期,即使其单列的一行...如果未索引日期,数据库也需要检查每个行记录以确定哪个是最大的。
两个查询将在log(action, token, id)
上的索引很快运行。
要了解这两个查询之间的性能差异,请为它们提供explain
计划。您可以通过explain
之前的查询来获得此问题:
explain SELECT date FROM `log` WHERE `action` = 'SOMETHING' and token = 167 ORDER BY id DESC LIMIT 1;
explain SELECT max(date) FROM `log` WHERE `action` = 'SOMETHING' and token = 167;
第一个命令对表和第一个记录进行排序。第二个命令尽管不订购,但DB需要读取整个表以找出哪个是最高记录。另外,您的表可能没有字段日期
这两个查询是非常不同的逻辑,尽管由于ID和日期之间的相关性可能会返回相同的值,这对您有意义,但是查询优化者显然不知道。/p>
使用索引(操作,令牌,日期),优化器可能能够更快地执行第二个查询,但是如果您绝对确定该相关性,则使用第一个查询没有错。