我正在使用超过2百万条记录的“用户”表。查询是:
SELECT * FROM users WHERE 1 ORDER BY firstname LIMIT $start,30
“firstname”列已编入索引。获取第一页非常快,而获取最后一页非常慢。
我使用了EXPLAIN,结果如下:
代表
EXPLAIN SELECT * FROM `users` WHERE 1 ORDER BY `firstname` LIMIT 10000 , 30
我得到了:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users index NULL firstname 194 NULL 10030
但是
EXPLAIN SELECT * FROM `users` WHERE 1 ORDER BY `firstname` LIMIT 100000 , 30
我正在
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users ALL NULL NULL NULL NULL 2292912 Using filesort
问题是什么?
答案 0 :(得分:3)
您不应该使用限制来覆盖数据集。
使用范围查询,您将获得更多更好的结果。
SELECT * FROM users
WHERE firstname >= last_used_name
ORDER BY firstname
LIMIT 30
last_used_name
是你已经看过的那个(我假设你做了某种批量处理)。如果对具有唯一索引的列执行范围查询,则会获得更准确的结果。这样你就不会两次获得相同的记录。
当你这样做时
LIMIT 100000 , 30
MySQL基本上与
中的相同LIMIT 100030
只有它不会返回前100万。但它会对它们进行排序和读取。
答案 1 :(得分:0)
对于没有WHERE条件的*
查询,MySQL通常不使用任何索引。
以下查询应该更快并且使用索引:
SELECT *
FROM (
SELECT user_id
FROM users
WHERE 1
ORDER BY firstname
LIMIT $start, 30) ids
JOIN users
USING (user_id);
user_id
是主键。