インデックス付きの「create_at」フィールドを持つテーブルがあります。いくつかの集計クエリを実行する必要がありますが、インデックスを使用して範囲を縮小することは効果的ではありません。
すべてのテーブル:
SELECT COUNT(1) FROM subscriptions
=> 412288行
2011年のみ:
SELECT COUNT(1) FROM subscriptions
WHERE (created_at BETWEEN '2011-01-01 00:00:00' AND '2011-12-31 23:59:59')
=> 95217 行
2011 年を月別に集計:
SELECT SQL_NO_CACHE MONTH(created_at) AS agg_created_at, SUM(amount) AS agg_amount
FROM subscriptions
WHERE (created_at BETWEEN '2011-01-01 00:00:00' AND '2011-12-31 23:59:59')
GROUP BY agg_created_at
ORDER BY agg_created_at
=> 0.1398 秒
+----+-------------+---------------+------+---------------+------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+---------------+------+---------+------+--------+----------------------------------------------+
| 1 | SIMPLE | subscriptions | ALL | created_at | NULL | NULL | NULL | 422807 | Using where; Using temporary; Using filesort |
+----+-------------+---------------+------+---------------+------+---------+------+--------+----------------------------------------------+
force index を使用した同じクエリ:
SELECT SQL_NO_CACHE MONTH(created_at) AS agg_created_at, SUM(amount) AS agg_amount
FROM subscriptions FORCE INDEX(created_at)
WHERE (created_at BETWEEN '2011-01-01 00:00:00' AND '2011-12-31 23:59:59')
GROUP BY agg_created_at
ORDER BY agg_created_at
=> 0.1283 秒
+----+-------------+---------------+-------+---------------+------------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+---------------+------------+---------+------+--------+----------------------------------------------+
| 1 | SIMPLE | subscriptions | range | created_at | created_at | 8 | NULL | 194106 | Using where; Using temporary; Using filesort |
+----+-------------+---------------+-------+---------------+------------+---------+------+--------+----------------------------------------------+
インデックスを使用して範囲を縮小することは効果がないため、オプティマイザーはここでは賢いようですが、その理由はわかりません。誰かに説明があれば?