Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Pierwsza kolumna o wyższej kardynalności w indeksie, gdy dotyczy zakresu?

Najpierw spróbujmy FORCE INDEX aby wybrać ef lub fe . Czasy są zbyt krótkie, aby uzyskać jasny obraz tego, który z nich jest szybszy, ale `EXPLAIN pokazuje różnicę:

Wymuszanie zakresu na filetime pierwszy. (Uwaga:kolejność w WHERE nie ma wpływu.)

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 |
+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+

Wymuszanie niskiej kardynalności ext po pierwsze:

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 |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

Oczywiście rows mówi ef jest lepiej. Sprawdźmy jednak za pomocą śladu Optymalizatora. Dane wyjściowe są dość obszerne; Pokażę tylko interesujące części. Brak FORCE jest potrzebne; ślad pokaże obie opcje, a następnie wybierz lepszą.

             ...
             "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
              }
            }

Z fe (najpierw kolumna zakresu), zakres mógł zostać użyty, ale oszacowano skanowanie przez 16684 wierszy wyławiających ext='gif' .

Z ef (niska kardynalność ext po pierwsze), może korzystać z obu kolumn indeksu i bardziej efektywnie drążyć w BTree. Następnie znalazł około 538 wierszy, z których wszystkie są przydatne w zapytaniu – nie jest potrzebne dalsze filtrowanie.

Wnioski:

  • INDEX(filetime, ext) użyto tylko pierwszej kolumny.
  • INDEX(ext, filetime) użył obu kolumn.
  • Umieść kolumny zaangażowane w = testy pierwsze w indeksie niezależnie od kardynalności .
  • Plan zapytań nie wyjdzie poza pierwszą kolumnę „zakresu”.
  • „Liczność” nie ma znaczenia w przypadku indeksów złożonych i tego typu zapytań .

(„Użycie warunku indeksu” oznacza, że ​​aparat pamięci masowej (InnoDB) użyje kolumn indeksu poza kolumną używaną do filtrowania.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Używanie Pythona i MySQL w procesie ETL:SQLAlchemy

  2. Jak chronić bazy danych MySQL przed kampaniami ransomware

  3. Objaśnienie struktury MySQL High Availability Framework – część I:Wprowadzenie

  4. Obsługa połączeń i ograniczanie przepustowości za pomocą ProxySQL

  5. Jak uzyskać następny identyfikator automatycznego przyrostu w mysql