简而言之:一个包含超过1600万条记录的表[大小为2GB]。当使用ORDER BY *primary_key*时,SELECT的LIMIT偏移量越高,查询就越慢
So
SELECT * FROM large ORDER BY `id` LIMIT 0, 30
花费远远少于
SELECT * FROM large ORDER BY `id` LIMIT 10000, 30
只订购了30张唱片,两者都一样。这不是ORDER BY的开销。
现在,当获取最近的30行时,大约需要180秒。如何优化这个简单的查询?
我发现了一个有趣的例子来优化SELECT查询ORDER BY id LIMIT X,Y。
我有3500万行,所以我花了2分钟找到一个行范围。
诀窍是这样的:
select id, name, address, phone
FROM customers
WHERE id > 990
ORDER BY id LIMIT 1000;
只要把WHERE和最后一个id放在一起,性能就会提高很多。对我来说是2分钟到1秒:)
这里还有其他有趣的技巧:http://www.iheavy.com/2013/06/19/3-ways-to-optimize-for-paging-in-mysql/
它也适用于字符串
我发现了一个有趣的例子来优化SELECT查询ORDER BY id LIMIT X,Y。
我有3500万行,所以我花了2分钟找到一个行范围。
诀窍是这样的:
select id, name, address, phone
FROM customers
WHERE id > 990
ORDER BY id LIMIT 1000;
只要把WHERE和最后一个id放在一起,性能就会提高很多。对我来说是2分钟到1秒:)
这里还有其他有趣的技巧:http://www.iheavy.com/2013/06/19/3-ways-to-optimize-for-paging-in-mysql/
它也适用于字符串
MySQL不能直接到第10000条记录(或者你建议的第80000个字节),因为它不能假设它是这样打包/排序的(或者它有从1到10000的连续值)。尽管实际上可能是这样,但MySQL不能假设没有漏洞/空白/删除的id。
因此,正如bobs所指出的,MySQL将不得不在找到要返回的30行之前获取10000行(或在id上遍历索引的10000个条目)。
编辑:为了说明我的观点
请注意,尽管
SELECT * FROM large ORDER BY id LIMIT 10000, 30
会很慢,
SELECT * FROM large WHERE id > 10000 ORDER BY id LIMIT 30
将是fast(er),并且将返回相同的结果,前提是没有缺失的id(即间隙)。