要跟进这个问题:我发现一些结果与Sean McSomething所描述的非常不同:
我有一张大约300M行的表。
Select max(foo) from bar;
大约需要15秒。运行
Select foo from bar order by foo desc limit 1;
需要3秒。运行
编辑:由于我无法在此处显示表的结构:假设bar是ndb_cluster中没有关系的表,foo是没有索引的任意数据点。
答案 0 :(得分:6)
要避免完整通过,请在INDEX
列上添加foo
。
答案 1 :(得分:1)
我遇到了这个问题,并认为我添加了我发现的内容。请注意,列已编制索引。我在MariaDB 10.2.14上运行。
我有一个类似SELECT MAX(created) FROM tbl WHERE group=0 AND created IS NOT NULL
的查询。 (group,created)
上有一个索引(两者都是整数,但创建的可以为NULL)。 group=0
有很多条目,created IS NULL
的条目不多。 tbl
正在使用Aria存储引擎。
EXPLAIN显示正在使用的索引,并且行数为46312,额外说法"使用where;使用索引"
运行查询需要大约0.692秒,但状态有一些有趣的东西:
Handler_read_key: 1
Handler_read_next: 45131
Handler_read_prev: 0
这似乎表明该密钥正在被最大限度地完全扫描;使用MIN代替MAX似乎给出了类似的结果。这似乎表明MIN / MAX实际上无法利用优化来选择索引的第一个/最后一个条目。
但是,如果查询更改为SELECT created FROM tbl WHERE group=0 AND created IS NOT NULL ORDER BY created DESC LIMIT 1
,而查询似乎需要大约相同的运行时间,并且EXPLAIN显示相同的信息,则状态显示:
Handler_read_key: 1
Handler_read_next: 0
Handler_read_prev: 0
如果将订单更改为ASC,我会得到类似的结果。在我看来,使用ORDER BY ... LIMIT可以跳过索引扫描,如果有很多行符合索引条件,如果我的理解是正确的话,这可能导致更快的查询。
请注意,对于上述结果,已经分配了足够的RAM和缓存来保存缓存中的所有索引,因此,可能是索引扫描很快。
我还没有完成其他条件(不同的MySQL版本和存储引擎)的任何实验,但我想这个故事的道德是,通过SHOW SESSION STATUS
检查查询状态可能有助于为这些事情提供答案。
至少在这种情况下,即使可以使用索引,ORDER BY ... LIMIT也可能比MIN / MAX更有效。
答案 2 :(得分:0)
我有一个类似的情况,有关列的索引,但顺序由&限制解决方案似乎更快。这有多好:)