Mysql
 sql >> база данни >  >> RDS >> Mysql

Колона с по-висока мощност първа в индекс, когато включва диапазон?

Първо, нека опитаме FORCE INDEX за да изберете или ef или fe . Времената са твърде кратки, за да получите ясна картина кое е по-бързо, но EXPLAIN показва разлика:

Принудително налагане на диапазона на filetime първо. (Забележка:Редът в WHERE няма влияние.)

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

Принудително използване на ext с ниска мощност първо:

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

Ясно е, че rows казва ef е по-добре. Но нека проверим с трасето на оптимизатора. Резултатът е доста обемист; Ще покажа само интересните части. Няма FORCE е необходимо; трасирането ще покаже и двете опции, след което изберете по-добрата.

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

С fe (първа колона за диапазон), диапазонът може да се използва, но се изчислява, че сканирането през 16684 реда търси ext='gif' .

С ef (ниска мощност ext първо), той може да използва и двете колони на индекса и да разбие по-ефективно в BTree. След това откри приблизително 538 реда, всички от които са полезни за заявката – не е необходимо допълнително филтриране.

Заключения:

  • INDEX(filetime, ext) използва само първата колона.
  • INDEX(ext, filetime) използва и двете колони.
  • Поставете колони, включени в = тества първо в индекса независимо от кардиналността .
  • Планът на заявката няма да надхвърли първата колона „диапазон“.
  • „Кардиналност“ е без значение за съставните индекси и този тип заявка .

(„Използване на условие за индекс“ означава, че Storage Engine (InnoDB) ще използва колони от индекса извън тази, използвана за филтриране.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Сравнете само ден и месец с поле за дата в mysql

  2. Как да изберете дата от колона дата и час?

  3. Как да се свържете с MySQL от командния ред

  4. Как да изградите JSON масив от mysql база данни

  5. Настройване на Laravel на Mac php artisan мигриране грешка:Няма такъв файл или директория