【发布时间】:2021-12-04 06:50:57
【问题描述】:
SELECT MAX vs ORDER BY LIMIT 1 个问题已经在这里回答了好几次了,但是如果我添加一个 WHERE 子句,事情就会发生巨大的变化
这是我的桌子:
| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| id | b'int' | 'NO' | 'PRI' | None | 'auto_increment' |
| 'open_time' | b'bigint' | 'NO' | 'UNI' | None | '' |
请注意,这两列都已编入索引。
以下是请求:
SELECT id from table
WHERE open_time > 0
ORDER BY id DESC LIMIT 1
SELECT MAX(id) from BTCUSDT1mHist
WHERE open_time > 0
EXPLAIN ANALYZE 显示以下内容: 订购:
-> Limit: 1 row(s) (cost=0.10 rows=1) (actual time=0.038..0.038 rows=1 loops=1)
-> Filter: (table.open_time > 0) (cost=0.10 rows=1) (actual time=0.037..0.037 rows=1 loops=1)
-> Index scan on table using PRIMARY (reverse) (cost=0.10 rows=2) (actual time=0.036..0.036 rows=1 loops=1)
MAX():
-> Aggregate: max(table.id) (cost=325890.06 rows=1081033) (actual time=1025.181..1025.181 rows=1 loops=1)
-> Filter: (table.open_time > 0) (cost=217786.76 rows=1081033) (actual time=0.032..866.890 rows=2180645 loops=1)
-> Index range scan on table using open_time (cost=217786.76 rows=1081033) (actual time=0.031..705.926 rows=2180645 loops=1)
ORDER BY 在 0.0012 秒内完成,而 MAX() 在 1.026 秒内完成
我也读过这个question,但它似乎没有涵盖我的情况
问题是:为什么 MAX() 花费的时间比 ORDER BY LIMIT 长这么多?
【问题讨论】:
-
MAX查询会先获取open_time>0的所有行,然后检查所有
ids,找出id的最大值。使用 ORDER BY 的查询将使用 id 上的索引获取最后一条记录,然后检查 open_time>0,并返回这条记录,如果第一个找到的记录恰好有一个 open_time>0,则速度会更快。 -
@Luuk 可能是这样,但是 SQL 操作的顺序应该首先是 WHERE,然后是 ORDER BY 和 LIMIT,然后是 eversql.com/…
-
一般来说你可能是对的,但是 MySQL 看到
ORDER BY id LIMIT 1,并决定读取主键是最有效的,所以它评估WHERE在第二步。在另一个查询中没有 ORDER BY,但 where 子句使用 open_time,并且该字段上有一个索引,使 MySQL 选择该索引。