Основы
индексирования и
расширенные
возможности
EXPLAIN MySQLв
Василий
Лукьянчико
в
План
• Архитектура
• Основы индексирования
• EXPLAIN (примеры)
Архитектура MySQL
Индексы
CREATE TABLE test (
id int not null auto_increment PRIMARY KEY,
…
INDEX(id),
UNIQUE(id));
index(A) ненужен при index(A,B) (если обаb-tree)
whereB=5 <=> whereA in (0,1) and B=5
(select .. whereA=0 and B=5 order by C limit 10)
union all
(select .. whereA=1 and B=5 order by C limit 10)
order by C limit 10;
Составные индексы
index(A,B,C) только последовательно и без пропусков
WHEREA=10AND B>405;
WHERE B=10AND A=9AND C<504;
WHEREA=10AND B=7 ORDER BY C;
WHERE B=3;
WHEREA=10AND B>4AND C>17;
WHEREA=10 ORDER BY C;
WHEREA=10 ORDER BY B, C;
WHEREA=10 ORDER BY B, C DESC;
Индексы не работают
• часть выражения: id + 1 = 3
year(key)=2015 <=> key between ‘2015-01-01’ and ‘2015-12-31’
• преобразованиетипов: key_str = 15
• несоответствиекодировок: key.utf = key.latin
• неиспользуется левая часть составного индекса:
index(a,b); whereb = x
• поиск по суффиксу:
key like‘%x’
• сравнениес исходной таблицей: t.key = t.col
index condition pushdown
WHEREA=10AND B like‘%x’;
WHEREA=10AND C=7;
Extended keys
вторичныеinnodb индексы имеют «хвост» из первичного
primary (A, B)
index(C) => (C, A, B)
index(B, C) => (B, C, A), не(B, C, A, B)
только для фильтрации строк
MariaDB 5.5 / MySQL 5.6
Ограничения оптимизатора
• мало статистики
• неучитывает особенности хранилищ, нагрузку, буферы
соединений и кэши
• метрика
• сложность выбора
• использует правила
whereabetween 1 and 4
wherea>0 and a< 5
Оптимизатор
• Проверканатривиальность
• Преобразованиезапроса
• Реестр индексов
• Выбирает самый дешевый план
Учитывает:
• SHOW CREATE TABLE и SHOW TABLE STATUS
• SHOW INDEX
• статистическая информация об индексах
• независимая статистика
Влияние на оптимизатор
• переписать запрос
• индексы
• use/force/ignoreindex
• straight_join
• @@optimizer_switch
• optimizer_prune_level и optimizer_search_depth
SQL_CALC_FOUND_ROWS
SELECT SQL_CALC_FOUND_ROWS... LIMIT ...
SELECT ... LIMIT ...
SELECT COUNT(*) ...
2 задачи – 1 метод
непозволяет использовать ряд оптимизаций
Недостатки explain
• неучитывает хранимыефункции
• может обмануть
• мало информации: план совпадает – производительность нет;
одинаковыетермины для различных ситуаций
• выполнениеfrom подзапросов
• может выполняться дольше, чем сам запрос
• оптимален ли план?
• соответствует ли тому, что было насамом деле?
Виды explain
EXPLAIN PARTITIONS..
EXPLAIN EXTENDED ..
SHOW WARNINGS;
sql запрос восстановленный из планавыполнения
<auto_key>
<cache>(expr)
<primary_index_lookup>(query fragment)
outer_tablessemi join (inner_tables)
/* select#N */ select_stmt
EXPLAIN SELECT city.nameFROM country JOIN city ON countrycode= code
WHERE continent='Europe' ORDER BY city.population DESC LIMIT 5G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4079
Extra: Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: country
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: test.city.CountryCode
rows: 1
Extra: Using where
Результат EXPLAIN
id - идентификатор результата
select_ type - тип запроса:
• SIMPLE - простой запрос (без UNION и без подзапросов);
• PRIMARY - внешний запрос по отношению к подзапросу или первый запрос в
объединении;
• UNION - второй или последующиезапросы в объединении (UNION);
• DEPENDENT UNION - второй или последующиезапросы в объединении (UNION),
зависящиеот внешнего запроса;
• UNION RESULT - отдельная строчкадля результатаобъединения;
• DERIVED - подзапрос, размещенный в области FROM.
• SUBQUERY, DEPENDENT SUBQUERY - подзапрос или зависимый от внешнего
запросаподзапрос;
• MATERIALIZED – материализация подзапроса
Результат EXPLAIN
table - имя таблицы
Результат EXPLAIN
Результат EXPLAIN
Пример
SELECT actor_id,
(SELECT 1 FROM sakila.film_actor
WHERE film_actor.actor_id = der_1.actor_id LIMIT 1)
FROM (
SELECT actor_id FROM sakila.actor LIMIT 5
) ASt1
UNION ALL
SELECT film_id,
(SELECT @var1 FROM sakila.rental LIMIT 1)
FROM (
SELECT film_id,
(SELECT 1 FROM sakila.storeLIMIT 1)
FROM sakila.film LIMIT 5
) ASt2;
Результат EXPLAIN
type- тип доступак таблице:
NULL - результат запросаможет быть получен без обращения к
таблицеили индексу.
system - специальный способ обращения к таблицам, содержащим
только одну строку;
const - запрос выполняется по уникальному ключу и приводит к
формированию неболее, чем одной строки;
eq_ref - запрос выполняется по уникальному ключу и приводит к
формированию неболее, чем одной строки для каждого
значения данных из внешнего запроса;
ref - запрос выполняется с использованием неуникального индекса
или с использованием левой части уникального индекса(которая
самапо себеявляется неуникальным индексом);
type продолжение
ref_or_null - аналогично типу ref, но в случае, если ключ допускает
значения NULL;
index_merge– использует несколько индексов.
unique_subquery - подзапрос в области IN заменяется на
дополнительноеусловиев части WHERE, осуществляющее
функцию просмотраиндекса; в этом случаенет накладных
расходов навыполнениеподзапроса. Работает только для
подзапросов видаvalueIN (SELECT primary_key FROM
single_tableWHERE some_expr);
index_subquery - аналогично unique_subquery, но без требования
уникальности индекса. Работает для подзапросов видаvalueIN
(SELECT key_column FROM single_tableWHERE some_expr);
type продолжение
range- индекс используется для операций неравенства(>, <, >=, <=,
LIKE, BETWEEN);
index - относится к двум типам доступа: (а) всеколонки,
используемыев запросе, присутствуют в индексе, поэтому
запрос может быть выполнен без обращения к данным таблицы,
(б) обход таблицы производится в порядке, заданном индексом;
ALL - производится полный скан таблицы (FTS- full tablescan).
Результат EXPLAIN
key - индекс, который решено использовать (USE INDEX, IGNORE
INDEX);
key_len - длинаиндексаили используемой части индексав байтах;
ref - если тип доступак таблицеимеет одно из следующих значений
(eq_ref, ref, ref_or_null, index_subquery, unique_subquery), то поле
содержит:
• именаколонок другой таблицы, используемыепри обращении
к индексу
• const, если обращениек индексу производится по заданному
константному значению
• func, если значение, по которому производится обращениек
индексу, является результатом функции.
В остальных случаях полепринимает значениеnull;
Результат EXPLAIN
rows- число строк, которыеMySQL ожидает перебрать для
выполнения данного запроса(ANALYZE TABLE;)
Extra- дополнительная информация:
Using filesort - файловая сортировкарезультата(в памяти или на
диске, в зависимости от объемаданных);
Using temporary - созданиевременной таблицы (в памяти или на
диске, в зависимости от объемаданных и значения минимальной
из переменных max_heap_table_sizeи tmp_table_size);
Using index - всеколонки, используемыев запросе, присутствуют
в индексе, поэтому запрос может быть выполнен без обращения
к данным таблицы (частный случай (а) типадоступаindex);
Профилирование
select c1 from t1 where(c1,c11) in
(select c2,c22 fromt2 wherec2>1 and c22<20)
         id: 2
select_type: DEPENDENT SUBQUERY
    table: t2
     type: index_subquery
SET profiling=1;
SELECT ...
SELECT STATE, COUNT(*), FORMAT(SUM(DURATION), 6) AS
DURATION
    FROM INFORMATION_SCHEMA.PROFILING
    WHERE QUERY_ID = 1 GROUPBY STATE;
Профилирование
Сортировка
может использовать индекс:
• левый префикс, если нет where, join
• если join, то только столбцы из 1ой таблицы
• сортировкав одном направлении
ORDER BY rand()
GROUPBY x ORDER BY null
ORDER BY id LIMIT 10000, 10
пример продолжение
ORDER BY + LIMIT
ORDER BY + LIMIT
Сортировка
Неравенства
select .. whereA<10 and B<20 and C=5;
секционирование
(C,A) или (C,B)
исключить одно из условий
Улучшения EXPLAIN
EXPLAIN для INSERT/UPDATE/DELETE
SHOW EXPLAIN
JSON формат для EXPLAIN
ANALYZE statement..
SHOW EXPLAIN
show processlist;
SHOW EXPLAIN FOR <thread_id>;
show warnings; -- показывает запрос
возможность сохранить в лог медленных запросов
[mysqld]
log-slow-verbosity=query_plan,explain
EXPLAIN format=json
Спасибо за внимание
/вопросы ответы
SQLinfo.ru/forum/

Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лукьянчиков (ООО «Станигост»)

  • 1.
  • 2.
    План • Архитектура • Основыиндексирования • EXPLAIN (примеры)
  • 3.
  • 4.
    Индексы CREATE TABLE test( id int not null auto_increment PRIMARY KEY, … INDEX(id), UNIQUE(id)); index(A) ненужен при index(A,B) (если обаb-tree) whereB=5 <=> whereA in (0,1) and B=5 (select .. whereA=0 and B=5 order by C limit 10) union all (select .. whereA=1 and B=5 order by C limit 10) order by C limit 10;
  • 5.
    Составные индексы index(A,B,C) толькопоследовательно и без пропусков WHEREA=10AND B>405; WHERE B=10AND A=9AND C<504; WHEREA=10AND B=7 ORDER BY C; WHERE B=3; WHEREA=10AND B>4AND C>17; WHEREA=10 ORDER BY C; WHEREA=10 ORDER BY B, C; WHEREA=10 ORDER BY B, C DESC;
  • 6.
    Индексы не работают •часть выражения: id + 1 = 3 year(key)=2015 <=> key between ‘2015-01-01’ and ‘2015-12-31’ • преобразованиетипов: key_str = 15 • несоответствиекодировок: key.utf = key.latin • неиспользуется левая часть составного индекса: index(a,b); whereb = x • поиск по суффиксу: key like‘%x’ • сравнениес исходной таблицей: t.key = t.col
  • 7.
    index condition pushdown WHEREA=10ANDB like‘%x’; WHEREA=10AND C=7;
  • 8.
    Extended keys вторичныеinnodb индексыимеют «хвост» из первичного primary (A, B) index(C) => (C, A, B) index(B, C) => (B, C, A), не(B, C, A, B) только для фильтрации строк MariaDB 5.5 / MySQL 5.6
  • 9.
    Ограничения оптимизатора • малостатистики • неучитывает особенности хранилищ, нагрузку, буферы соединений и кэши • метрика • сложность выбора • использует правила whereabetween 1 and 4 wherea>0 and a< 5
  • 10.
    Оптимизатор • Проверканатривиальность • Преобразованиезапроса •Реестр индексов • Выбирает самый дешевый план Учитывает: • SHOW CREATE TABLE и SHOW TABLE STATUS • SHOW INDEX • статистическая информация об индексах • независимая статистика
  • 12.
    Влияние на оптимизатор •переписать запрос • индексы • use/force/ignoreindex • straight_join • @@optimizer_switch • optimizer_prune_level и optimizer_search_depth
  • 13.
    SQL_CALC_FOUND_ROWS SELECT SQL_CALC_FOUND_ROWS... LIMIT... SELECT ... LIMIT ... SELECT COUNT(*) ... 2 задачи – 1 метод непозволяет использовать ряд оптимизаций
  • 14.
    Недостатки explain • неучитываетхранимыефункции • может обмануть • мало информации: план совпадает – производительность нет; одинаковыетермины для различных ситуаций • выполнениеfrom подзапросов • может выполняться дольше, чем сам запрос • оптимален ли план? • соответствует ли тому, что было насамом деле?
  • 15.
    Виды explain EXPLAIN PARTITIONS.. EXPLAINEXTENDED .. SHOW WARNINGS; sql запрос восстановленный из планавыполнения <auto_key> <cache>(expr) <primary_index_lookup>(query fragment) outer_tablessemi join (inner_tables) /* select#N */ select_stmt
  • 16.
    EXPLAIN SELECT city.nameFROMcountry JOIN city ON countrycode= code WHERE continent='Europe' ORDER BY city.population DESC LIMIT 5G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: city type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4079 Extra: Using filesort *************************** 2. row *************************** id: 1 select_type: SIMPLE table: country type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 3 ref: test.city.CountryCode rows: 1 Extra: Using where
  • 17.
    Результат EXPLAIN id -идентификатор результата select_ type - тип запроса: • SIMPLE - простой запрос (без UNION и без подзапросов); • PRIMARY - внешний запрос по отношению к подзапросу или первый запрос в объединении; • UNION - второй или последующиезапросы в объединении (UNION); • DEPENDENT UNION - второй или последующиезапросы в объединении (UNION), зависящиеот внешнего запроса; • UNION RESULT - отдельная строчкадля результатаобъединения; • DERIVED - подзапрос, размещенный в области FROM. • SUBQUERY, DEPENDENT SUBQUERY - подзапрос или зависимый от внешнего запросаподзапрос; • MATERIALIZED – материализация подзапроса
  • 18.
  • 19.
  • 20.
  • 21.
    Пример SELECT actor_id, (SELECT 1FROM sakila.film_actor WHERE film_actor.actor_id = der_1.actor_id LIMIT 1) FROM ( SELECT actor_id FROM sakila.actor LIMIT 5 ) ASt1 UNION ALL SELECT film_id, (SELECT @var1 FROM sakila.rental LIMIT 1) FROM ( SELECT film_id, (SELECT 1 FROM sakila.storeLIMIT 1) FROM sakila.film LIMIT 5 ) ASt2;
  • 23.
    Результат EXPLAIN type- типдоступак таблице: NULL - результат запросаможет быть получен без обращения к таблицеили индексу. system - специальный способ обращения к таблицам, содержащим только одну строку; const - запрос выполняется по уникальному ключу и приводит к формированию неболее, чем одной строки; eq_ref - запрос выполняется по уникальному ключу и приводит к формированию неболее, чем одной строки для каждого значения данных из внешнего запроса; ref - запрос выполняется с использованием неуникального индекса или с использованием левой части уникального индекса(которая самапо себеявляется неуникальным индексом);
  • 24.
    type продолжение ref_or_null -аналогично типу ref, но в случае, если ключ допускает значения NULL; index_merge– использует несколько индексов. unique_subquery - подзапрос в области IN заменяется на дополнительноеусловиев части WHERE, осуществляющее функцию просмотраиндекса; в этом случаенет накладных расходов навыполнениеподзапроса. Работает только для подзапросов видаvalueIN (SELECT primary_key FROM single_tableWHERE some_expr); index_subquery - аналогично unique_subquery, но без требования уникальности индекса. Работает для подзапросов видаvalueIN (SELECT key_column FROM single_tableWHERE some_expr);
  • 25.
    type продолжение range- индексиспользуется для операций неравенства(>, <, >=, <=, LIKE, BETWEEN); index - относится к двум типам доступа: (а) всеколонки, используемыев запросе, присутствуют в индексе, поэтому запрос может быть выполнен без обращения к данным таблицы, (б) обход таблицы производится в порядке, заданном индексом; ALL - производится полный скан таблицы (FTS- full tablescan).
  • 26.
    Результат EXPLAIN key -индекс, который решено использовать (USE INDEX, IGNORE INDEX); key_len - длинаиндексаили используемой части индексав байтах; ref - если тип доступак таблицеимеет одно из следующих значений (eq_ref, ref, ref_or_null, index_subquery, unique_subquery), то поле содержит: • именаколонок другой таблицы, используемыепри обращении к индексу • const, если обращениек индексу производится по заданному константному значению • func, если значение, по которому производится обращениек индексу, является результатом функции. В остальных случаях полепринимает значениеnull;
  • 27.
    Результат EXPLAIN rows- числострок, которыеMySQL ожидает перебрать для выполнения данного запроса(ANALYZE TABLE;) Extra- дополнительная информация: Using filesort - файловая сортировкарезультата(в памяти или на диске, в зависимости от объемаданных); Using temporary - созданиевременной таблицы (в памяти или на диске, в зависимости от объемаданных и значения минимальной из переменных max_heap_table_sizeи tmp_table_size); Using index - всеколонки, используемыев запросе, присутствуют в индексе, поэтому запрос может быть выполнен без обращения к данным таблицы (частный случай (а) типадоступаindex);
  • 28.
    Профилирование select c1 fromt1 where(c1,c11) in (select c2,c22 fromt2 wherec2>1 and c22<20)          id: 2 select_type: DEPENDENT SUBQUERY     table: t2      type: index_subquery SET profiling=1; SELECT ... SELECT STATE, COUNT(*), FORMAT(SUM(DURATION), 6) AS DURATION     FROM INFORMATION_SCHEMA.PROFILING     WHERE QUERY_ID = 1 GROUPBY STATE;
  • 29.
  • 30.
    Сортировка может использовать индекс: •левый префикс, если нет where, join • если join, то только столбцы из 1ой таблицы • сортировкав одном направлении ORDER BY rand() GROUPBY x ORDER BY null ORDER BY id LIMIT 10000, 10
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
    Неравенства select .. whereA<10and B<20 and C=5; секционирование (C,A) или (C,B) исключить одно из условий
  • 37.
    Улучшения EXPLAIN EXPLAIN дляINSERT/UPDATE/DELETE SHOW EXPLAIN JSON формат для EXPLAIN ANALYZE statement..
  • 38.
    SHOW EXPLAIN show processlist; SHOWEXPLAIN FOR <thread_id>; show warnings; -- показывает запрос возможность сохранить в лог медленных запросов [mysqld] log-slow-verbosity=query_plan,explain
  • 39.
  • 40.