我有一个SQL查询
SELECT level, data, string, soln, uid
FROM user_data
WHERE level = 10 AND (timetaken >= 151 AND timetaken <= 217) AND uid != 1
LIMIT 8852, 1;
从一个包含150万个条目的表中获取。
我已使用
编入索引alter table user_data add index a_idx (level, timetaken, uid);
所以我面临的问题是在某些情况下查询需要超过30秒,在某些情况下查询时间小于0.01秒。
此处的索引是否存在任何问题。
编辑: 添加了解释查询详细信息
+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+
| 1 | SIMPLE | user_data | range | a_idx | a_idx | 30 | NULL | 24091 | Using where; Using index |
+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+
表格中的数据字段是文本字段。在大多数情况下,它的长度大于255个字符。这会导致问题吗?
答案 0 :(得分:0)
首先,您应该尝试使用EXPLAIN获取此查询的执行计划:
EXPLAIN SELECT level, data, string, soln, uid
FROM user_data
WHERE level = 10 AND (timetaken >= 151 AND timetaken <= 217) AND uid != 1
LIMIT 8852, 1;
这是关于此主题的一个很好的幻灯片: http://www.slideshare.net/phpcodemonkey/mysql-explain-explained
尝试添加不同的索引:
答案 1 :(得分:0)
问题在于高偏移量。为了选择8853rd结果,MySQL必须在此之前扫描所有8852行。
顺便说一下,使用没有订单的限制可能会导致意外结果。
为了加快具有高偏移量的查询,您应该转到since..until分页策略