Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Kolom kardinalitas yang lebih tinggi pertama dalam indeks ketika melibatkan rentang?

Pertama, mari kita coba FORCE INDEX untuk memilih ef atau fe . Pengaturan waktunya terlalu singkat untuk mendapatkan gambaran yang jelas tentang mana yang lebih cepat, tetapi `MENJELASKAN menunjukkan perbedaan:

Memaksa rentang pada filetime pertama. (Catatan:Urutan di WHERE tidak berdampak.)

mysql> EXPLAIN SELECT COUNT(*), AVG(fsize)
    FROM files FORCE INDEX(fe)
    WHERE ext = 'gif' AND filetime >= '2015-01-01'
                      AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;
+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows  | Extra                 |
+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+
|  1 | SIMPLE      | files | range | fe            | fe   | 14      | NULL | 16684 | Using index condition |
+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+

Memaksa ext- kardinalitas rendah pertama:

mysql> EXPLAIN SELECT COUNT(*), AVG(fsize)
    FROM files FORCE INDEX(ef)
    WHERE ext = 'gif' AND filetime >= '2015-01-01'
                      AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
|  1 | SIMPLE      | files | range | ef            | ef   | 14      | NULL |  538 | Using index condition |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

Jelas, rows mengatakan ef lebih baik. Tapi mari kita periksa dengan jejak Pengoptimal. Outputnya agak besar; Saya hanya akan menunjukkan bagian yang menarik. Tidak ada FORCE dibutuhkan; jejak akan menampilkan kedua opsi lalu pilih yang lebih baik.

             ...
             "potential_range_indices": [
                ...
                {
                  "index": "fe",
                  "usable": true,
                  "key_parts": [
                    "filetime",
                    "ext",
                    "did",
                    "filename"
                  ]
                },
                {
                  "index": "ef",
                  "usable": true,
                  "key_parts": [
                    "ext",
                    "filetime",
                    "did",
                    "filename"
                  ]
                }
              ],

...

              "analyzing_range_alternatives": {
                "range_scan_alternatives": [
                  {
                    "index": "fe",
                    "ranges": [
                      "2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"
                    ],
                    "index_dives_for_eq_ranges": true,
                    "rowid_ordered": false,
                    "using_mrr": false,
                    "index_only": false,
                    "rows": 16684,
                    "cost": 20022,               <-- Here's the critical number
                    "chosen": true
                  },
                  {
                    "index": "ef",
                    "ranges": [
                      "gif <= ext <= gif AND 2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"
                    ],
                    "index_dives_for_eq_ranges": true,
                    "rowid_ordered": false,
                    "using_mrr": false,
                    "index_only": false,
                    "rows": 538,
                    "cost": 646.61,               <-- Here's the critical number
                    "chosen": true
                  }
                ],

...

          "attached_conditions_computation": [
            {
              "access_type_changed": {
                "table": "`files`",
                "index": "ef",
                "old_type": "ref",
                "new_type": "range",
                "cause": "uses_more_keyparts"   <-- Also interesting
              }
            }

Dengan fe (kolom rentang terlebih dahulu), rentang dapat digunakan, tetapi diperkirakan memindai melalui 16684 baris memancing ext='gif' .

Dengan ef (kardinalitas rendah ext pertama), itu bisa menggunakan kedua kolom indeks dan menelusuri lebih efisien di BTree. Kemudian ditemukan sekitar 538 baris, yang semuanya berguna untuk kueri -- tidak perlu pemfilteran lebih lanjut.

Kesimpulan:

  • INDEX(filetime, ext) hanya menggunakan kolom pertama.
  • INDEX(ext, filetime) menggunakan kedua kolom.
  • Masukkan kolom yang terlibat dalam = tes pertama dalam indeks terlepas dari kardinalitas .
  • Rencana kueri tidak akan melampaui kolom 'rentang' pertama.
  • "Kardinalitas" tidak relevan untuk indeks komposit dan jenis kueri ini .

("Menggunakan kondisi indeks" berarti Storage Engine (InnoDB) akan menggunakan kolom indeks di luar kolom yang digunakan untuk pemfilteran.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sintaks SQL TRUNCATE – Didaftarkan oleh DBMS

  2. Cara membuat cadangan database MySQL menggunakan AutoMySQLBackup

  3. Fungsi Agregat MySQL tanpa klausa GROUP BY

  4. Memigrasikan Google Cloud SQL untuk MySQL ke Server Lokal

  5. Bagaimana cara mengaktifkan koneksi ulang otomatis klien MySQL dengan MySQLdb?