Rumah > Soal Jawab > teks badan
Saya mempunyai model yang dipanggil CacheSync dan mysql menunjukkan ia mempunyai indeks:
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)
Tetapi apabila saya menerangkannya, ia berkata ia tidak menggunakan indeks:
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)
Mengapa tidak menggunakan indeks?
Terima kasih atas bantuan anda, Kevin
P粉4211197782024-03-22 10:04:01
Menurut pengalaman saya, jika pengoptimum menganggarkan bahawa keadaan anda sepadan dengan lebih daripada 20% jadual, ia akan kembali kepada imbasan jadual. Ia meneka bahawa membaca semua baris daripada indeks berkelompok adalah lebih pantas daripada mencari nilai dalam indeks sekunder, dan kemudian melakukan carian lain untuk mendapatkan baris yang sepadan daripada jadual.
Ambang 20% bukanlah sebarang ciri rasmi, ia hanya apa yang saya perhatikan. Ia tidak boleh dikonfigurasikan dalam versi semasa MySQL.
Anda boleh menggunakan petunjuk indeks untuk meyakinkannya bahawa imbasan jadual adalah terlalu mahal:
SELECT ... FROM mytable FORCE INDEX (index_cache_syncs_on_created_at) WHERE ...
Ia hanya akan melakukan imbasan jadual jika indeks yang anda tentukan tidak berkaitan dengan syarat dalam pertanyaan.
Lihat https://dev.mysql.com/doc/refman/8.0/en/index-hints.html untuk mendapatkan maklumat lanjut tentang pembayang indeks.
Saya bukan pembangun Rails, tetapi jawapan lama ini menunjukkan cara untuk menghantar sintaks petunjuk indeks kepada Rails: https://stackoverflow.com/a/13904227/20860 Saya tidak tahu sama ada ini masih semasa berlatih.