两个 SQL 查询具有相同的结果,但一个速度要快一个数量级
Posted
技术标签:
【中文标题】两个 SQL 查询具有相同的结果,但一个速度要快一个数量级【英文标题】:Two SQL queries with the same result but one is a order of magnitude faster 【发布时间】:2014-01-21 17:08:56 【问题描述】:我想知道为什么第一个查询比第二个查询快得多。 它在大约 50 万条记录的表上运行。
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 列已编入索引,这有很大的不同。 要了解性能,您需要为查询提供explain
计划。
@a_horse_with_no_name 在查询末尾有命令LIMIT 1
@a_horse_with_no_name 对不起,正确的词是记录。
【参考方案1】:
我的猜测是您没有日期索引,但确实有 id(主键)索引?
如果 id 是主键,它可以对数据进行排序以更快地返回结果给您。这是因为即使您的查询只返回一个日期列,这些行也是按 id 排序的,id 是索引的,因此可以非常快速地排序 500k 行。
要返回最大日期,即使它是单列中的一行……如果日期没有被索引,数据库需要检查每一行记录以确定哪个是最大的。
【讨论】:
【参考方案2】:两个查询都将运行得非常快,索引为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;
【讨论】:
【参考方案3】:第一个命令对表进行排序并带来第一条记录。第二个命令虽然没有排序,但 db 需要读取整个表以找出最高记录。此外,您的表格可能没有字段日期的索引
【讨论】:
【参考方案4】:这两个查询是非常不同的逻辑,尽管它们可能返回相同的值,因为 id 和日期之间的相关性对您来说是有意义的,但查询优化器显然无法知道。
使用 (action, token, date) 上的索引,优化器可能能够更快地执行第二个查询,但如果您完全确定这种相关性,那么使用第一个查询没有任何问题。
【讨论】:
以上是关于两个 SQL 查询具有相同的结果,但一个速度要快一个数量级的主要内容,如果未能解决你的问题,请参考以下文章