sql >> Databáze >  >> RDS >> Mysql

Sloupec vyšší mohutnosti jako první v indexu při použití rozsahu?

Nejprve zkusme FORCE INDEX vyberte buď ef nebo fe . Časy jsou příliš krátké na to, abyste získali jasný obrázek o tom, co je rychlejší, ale „EXPLAIN ukazuje rozdíl:

Vynucení rozsahu na filetime za prvé. (Poznámka:Pořadí v WHERE nemá žádný dopad.)

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

Vynucení ext s nízkou mohutností první:

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

Jasně, rows říká ef je lepší. Ale pojďme to zkontrolovat pomocí trasování Optimalizátoru. Výstup je poměrně objemný; Ukážu jen ty zajímavé části. Žádná FORCE je potřeba; trasování zobrazí obě možnosti a poté vyberte tu lepší.

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

Pomocí fe (sloupec rozsahu jako první), rozsah lze použít, ale odhaduje se, že prohledá 16 684 řádků při hledání ext='gif' .

Pomocí ef (nízká mohutnost ext za prvé), mohl by použít oba sloupce indexu a efektivněji procházet dolů v BTree. Poté našel odhadem 538 řádků, z nichž všechny jsou užitečné pro dotaz – není potřeba žádné další filtrování.

Závěry:

  • INDEX(filetime, ext) používá pouze první sloupec.
  • INDEX(ext, filetime) použil oba sloupce.
  • Vložte sloupce zahrnuté do = testy nejprve v indexu bez ohledu na mohutnost .
  • Plán dotazů nepřesáhne první sloupec „rozsah“.
  • „Kardinálnost“ je irelevantní pro složené indexy a tento typ dotazu .

("Using index condition" znamená, že Storage Engine (InnoDB) bude používat sloupce indexu nad rámec toho, který se používá pro filtrování.)




  1. Django+Postgres:aktuální transakce je přerušena, příkazy ignorovány až do konce bloku transakce

  2. Jak vytvořit Serverless GraphQL API pro MySQL, Postgres a Aurora

  3. Použití Jenkinse s Kubernetes AWS, část 1

  4. java.util.MissingFormatArgumentException:Specifikátor formátu:s