我有一个运行速度比它应该慢得多的查询。我已将问题提炼为一个简单的选择语句(出于隐私考虑,某些字段已重命名):
SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS id, date_started, date_complete, status
FROM table_a
ORDER BY date DESC
LIMIT 0, 100
当SQL_CALC_FOUND_ROWS
使用时,查询在大约 0.70 秒内完成,但是当SQL_CALC_FOUND_ROWS
被移除时,查询在大约 0.0005 秒内完成(在这两种情况下SQL_NO_CACHE
都在查询中使用)。
table_a
date
在字段上有一个索引。
显然 SQL_CALC_FOUND_ROWS可以防止使用索引:
因此,从这个简单的测试中得出的明显结论是:当我们在查询中为 WHERE/ORDER 子句提供适当的索引时,使用两个单独的查询而不是一个使用 SQL_CALC_FOUND_ROWS 的查询要快得多。
我已经证实了这一点。包含时不使用索引SQL_CALC_FOUND_ROWS
:
EXPLAIN SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS id, date_started, date_complete, status FROM table_a ORDER BY date DESC limit 0, 100;
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
| 1 | SIMPLE | table_a | ALL | NULL | NULL | NULL | NULL | 132208 | Using filesort |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
但是当SQL_CALC_FOUND_ROWS
不使用时,则使用日期字段上的索引:
EXPLAIN SELECT SQL_NO_CACHE id, date_started, date_complete, status FROM table_a ORDER BY date DESC limit 0, 100;
+----+-------------+-------------+-------+---------------+------+---------+------+--------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+------+---------+------+--------+-------+
| 1 | SIMPLE | table_a | index | NULL | date | 13 | NULL | 132208 | |
+----+-------------+-------------+-------+---------------+------+---------+------+--------+-------+
有没有办法在不从查询中删除的情况下加快查询速度SQL_CALC_FOUND_ROWS
?
我正在使用 MySQL 版本 5.0.51a-3ubuntu5.1-log。