首頁  >  問答  >  主體

Rails created_at 索引未使用索引

我有一個名為CacheSync的模型,mysql顯示它有一個索引:

mysql> show indexes from cache_syncs;
+-------------+------------+---------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table       | Non_unique | Key_name                        | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------+------------+---------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| cache_syncs |          0 | PRIMARY                         |            1 | id          | A         |       90878 |     NULL | NULL   |      | BTREE      |         |               |
| cache_syncs |          1 | index_cache_syncs_on_created_at |            1 | created_at  | A         |       18175 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------------+------------+---------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.01 sec)

但是當我去解釋時,它說它沒有使用索引:

CacheSync.where("created_at < ?", (Time.now - 1.hour).to_time).explain
 =>
EXPLAIN for: SELECT `cache_syncs`.* FROM `cache_syncs` WHERE (created_at < '2022-06-13 19:37:23.316439')
+----+-------------+-------------+------+---------------------------------+------+---------+------+-------+-------------+
| id | select_type | table       | type | possible_keys                   | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------------+------+---------------------------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | cache_syncs | ALL  | index_cache_syncs_on_created_at | NULL | NULL    | NULL | 93651 | Using where |
+----+-------------+-------------+------+---------------------------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

為什麼不使用索引?

感謝您的幫助, 凱文

P粉384679266P粉384679266183 天前273

全部回覆(1)我來回復

  • P粉421119778

    P粉4211197782024-03-22 10:04:01

    根據我的經驗,如果優化器估計您的條件與表的 20% 以上匹配,它將回退到表掃描。它猜測從聚集索引中讀取所有行比在二級索引中查找值更快,然後再進行一次查找以從表中獲取相應的行。

    20% 的閾值不是任何官方功能,這只是我觀察到的。它在目前版本的 MySQL 中不可配置。

    您可以使用索引提示來說服它表掃描的成本過高:

    SELECT ... FROM mytable FORCE INDEX (index_cache_syncs_on_created_at) WHERE ...

    只有當您指定的索引與查詢中的條件無關時,它才會執行表格掃描。

    請參閱https://dev.mysql.com/ doc/refman/8.0/en/index-hints.html 有關索引提示的更多資訊。

    我不是Rails 開發人員,但這個舊答案顯示了一種向Rails 傳遞索引提示語法的方法:https:// stackoverflow.com/a/13904227/20860 我不知道這是否仍然是目前的做法。

    回覆
    0
  • 取消回覆