ORDER BY LIMIT查询的MySQL索引用法

use*_*172 5 mysql

我正在使用超过2百万条记录的"用户"表.查询是:

SELECT * FROM users WHERE 1 ORDER BY firstname LIMIT $start,30
Run Code Online (Sandbox Code Playgroud)

"firstname"列已编入索引.获取第一页非常快,而获取最后一页非常慢.

我使用了EXPLAIN,结果如下:

对于

EXPLAIN SELECT * FROM `users` WHERE 1 ORDER BY `firstname` LIMIT 10000 , 30
Run Code Online (Sandbox Code Playgroud)

我越来越:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  users   index   NULL    firstname   194     NULL    10030 
Run Code Online (Sandbox Code Playgroud)

但对于

EXPLAIN SELECT * FROM `users` WHERE 1 ORDER BY `firstname` LIMIT 100000 , 30
Run Code Online (Sandbox Code Playgroud)

我越来越

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  users   ALL     NULL    NULL    NULL    NULL    2292912     Using filesort
Run Code Online (Sandbox Code Playgroud)

有什么问题?

Ser*_*sev 3

您不应该使用 limit 来对数据集进行分页。

通过使用范围查询,您将获得更好的结果。

SELECT * FROM users 
WHERE firstname >= last_used_name 
ORDER BY firstname 
LIMIT 30
Run Code Online (Sandbox Code Playgroud)

您已经见过的一个在哪里last_used_name(我假设您进行某种批处理)。如果对具有唯一索引的列进行范围查询,您将获得更准确的结果。这样您就不会两次获得相同的记录。

当你这样做时

LIMIT 100000 , 30
Run Code Online (Sandbox Code Playgroud)

MySQL 本质上与

LIMIT 100030
Run Code Online (Sandbox Code Playgroud)

只是它不会返回前 10 万个。但它会对它们进行排序和读取。