Как узнать, что стоит за индексом `auto_key0` в MySQL? - PullRequest
0 голосов
/ 03 июля 2018

Говоря, у меня есть этот запрос:

EXPLAIN SELECT *
FROM (
    SELECT "A" as a, i.n FROM (SELECT 1 AS n) AS i
    UNION ALL SELECT "B" as a, i.n FROM (SELECT 1 AS n) AS i) AS t
WHERE a = "B";

MySQL говорит

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   PRIMARY <derived2>  \N  ref <auto_key0> <auto_key0> 6   const   1   100.00  \N
2   DERIVED <derived3>  \N  system  \N  \N  \N  \N  1   100.00  \N
3   DERIVED \N  \N  \N  \N  \N  \N  \N  \N  \N  No tables used
4   UNION   <derived5>  \N  system  \N  \N  \N  \N  1   100.00  \N
5   DERIVED \N  \N  \N  \N  \N  \N  \N  \N  \N  No tables used

Итак, MySQL сгенерировал промежуточный индекс <auto_key0>, но что стоит за этим индексом? Какие колонки в нем используются? И есть ли способ, которым я могу установить этот индекс вручную и заставить MySQL использовать некоторые столбцы.

Ответы [ 2 ]

0 голосов
/ 17 июля 2018

EXPLAIN FORMAT=JSON SELECT ... вернет что-то вроде

    key: <auto_key0>, used_key_parts: ['a'], key_length: 6, ref: ['const']

<auto_key0> - это индекс, сгенерированный оптимизатором для производной таблицы.

(Существует также «Трассировка оптимизатора», но, вероятно, нет этой конкретной информации.)

0 голосов
/ 03 июля 2018

https://dev.mysql.com/doc/refman/8.0/en/derived-table-optimization.html говорит:

SELECT *
FROM t1 JOIN (SELECT DISTINCT f1 FROM t2) AS derived_t2
     ON t1.f1=derived_t2.f1;

Оптимизатор создает индекс по столбцу f1 из производного_t2, если это позволило бы использовать ref-доступ для выполнения с наименьшими затратами план.

Я предполагаю, что столбцы индекса определяются выражением соединения. Оптимизатор MySQL знает, какой столбец (столбцы) будет полезен для индексации, поскольку на них есть ссылки в предложении ON объединения.

Я не знаю ни одного способа управления индексом, который генерируется для производной таблицы. Индекс недолговечный. Он создается для временной таблицы во время запроса и будет естественным образом удален при удалении временной таблицы в конце запроса.

Если вы хотите больше контролировать индексы, вам придется создать собственную таблицу (временную или постоянную) и определить для нее индексы.

Вы также можете прочитать этот блог на тему, написанную руководителем оптимизатора MySQL: https://mysqlserverteam.com/mysql-5-7-improved-performance-of-queries-with-derived-tables/

...