Основы индексирования и расширенные возможности EXPLAIN...
-
Upload
ontico -
Category
Engineering
-
view
6.841 -
download
3
Transcript of Основы индексирования и расширенные возможности EXPLAIN...
Основы индексирования и расширенные возможности 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)where B=5 <=> where A in (0,1) and B=5(select .. where A=0 and B=5 order by C limit 10)union all(select .. where A=1 and B=5 order by C limit 10)order by C limit 10;
Составные индексыindex(A,B,C) только последовательно и без пропусковWHERE A=10 AND B>405;WHERE B=10 AND A=9 AND C<504; WHERE A=10 AND B=7 ORDER BY C; WHERE B=3;WHERE A=10 AND B>4 AND C>17;WHERE A=10 ORDER BY C;WHERE A=10 ORDER BY B, C;WHERE A=10 ORDER BY B, C DESC;
Индексы не работают• часть выражения: id + 1 = 3year(key)=2015 <=> key between ‘2015-01-01’ and ‘2015-
12-31’• преобразование типов: key_str = 15• несоответствие кодировок: key.utf = key.latin• не используется левая часть составного индекса:index(a,b); where b = x• поиск по суффиксу:key like ‘%x’• сравнение с исходной таблицей: t.key = t.col
index condition pushdownWHERE A=10 AND B like ‘%x’; WHERE A=10 AND 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
Ограничения оптимизатора• мало статистики• не учитывает особенности хранилищ, нагрузку,
буферы соединений и кэши• метрика• сложность выбора• использует правила
where a between 1 and 4where a >0 and a < 5
Оптимизатор• Проверка на тривиальность• Преобразование запроса• Реестр индексов• Выбирает самый дешевый план
Учитывает:• SHOW CREATE TABLE и SHOW TABLE STATUS • SHOW INDEX • статистическая информация об индексах• независимая статистика
Влияние на оптимизатор• переписать запрос• индексы• use/force/ignore index• 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 подзапросов• может выполняться дольше, чем сам запрос• оптимален ли план?• соответствует ли тому, что было на самом деле?
Виды explainEXPLAIN PARTITIONS .. EXPLAIN EXTENDED ..SHOW WARNINGS;sql запрос восстановленный из плана выполнения<auto_key><cache>(expr) <primary_index_lookup>(query fragment)outer_tables semi join (inner_tables)/* select#N */ select_stmt
EXPLAIN SELECT city.name FROM country JOIN city ON countrycode = code WHERE continent='Europe' ORDER BY city.population DESC LIMIT 5\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: city type: ALLpossible_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_refpossible_keys: PRIMARY key: PRIMARY key_len: 3 ref: test.city.CountryCode rows: 1 Extra: Using where
Результат EXPLAINid - идентификатор результата
select_type - тип запроса: • SIMPLE - простой запрос (без UNION и без подзапросов); • PRIMARY - внешний запрос по отношению к подзапросу или первый
запрос в объединении; • UNION - второй или последующие запросы в объединении (UNION); • DEPENDENT UNION - второй или последующие запросы в
объединении (UNION), зависящие от внешнего запроса; • UNION RESULT - отдельная строчка для результата объединения; • DERIVED - подзапрос, размещенный в области FROM. • SUBQUERY, DEPENDENT SUBQUERY - подзапрос или зависимый от
внешнего запроса подзапрос; • MATERIALIZED – материализация подзапроса
Результат EXPLAINtable - имя таблицы
Результат 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) AS t1UNION ALLSELECT film_id, (SELECT @var1 FROM sakila.rental LIMIT 1)FROM ( SELECT film_id, (SELECT 1 FROM sakila.store LIMIT 1) FROM sakila.film LIMIT 5) AS t2;
Результат EXPLAINtype - тип доступа к таблице: NULL - результат запроса может быть получен без
обращения к таблице или индексу. system - специальный способ обращения к таблицам,
содержащим только одну строку; const - запрос выполняется по уникальному ключу и
приводит к формированию не более, чем одной строки;
eq_ref - запрос выполняется по уникальному ключу и приводит к формированию не более, чем одной строки для каждого значения данных из внешнего запроса;
ref - запрос выполняется с использованием неуникального индекса или с использованием левой части уникального индекса (которая сама по себе является неуникальным индексом);
type продолжениеref_or_null - аналогично типу ref, но в случае, если ключ
допускает значения NULL;index_merge – использует несколько индексов.unique_subquery - подзапрос в области IN заменяется
на дополнительное условие в части WHERE, осуществляющее функцию просмотра индекса; в этом случае нет накладных расходов на выполнение подзапроса. Работает только для подзапросов вида value IN (SELECT primary_key FROM single_table WHERE some_expr);
index_subquery - аналогично unique_subquery, но без требования уникальности индекса. Работает для подзапросов вида value IN (SELECT key_column FROM single_table WHERE some_expr);
type продолжениеrange - индекс используется для операций
неравенства (>, <, >=, <=, LIKE, BETWEEN);index - относится к двум типам доступа: (а) все
колонки, используемые в запросе, присутствуют в индексе, поэтому запрос может быть выполнен без обращения к данным таблицы, (б) обход таблицы производится в порядке, заданном индексом;
ALL - производится полный скан таблицы (FTS - full table scan).
Результат EXPLAINkey - индекс, который решено использовать (USE INDEX,
IGNORE INDEX);key_len - длина индекса или используемой части индекса
в байтах;ref - если тип доступа к таблице имеет одно из
следующих значений (eq_ref, ref, ref_or_null, index_subquery, unique_subquery), то поле содержит:
• имена колонок другой таблицы, используемые при обращении к индексу
• const, если обращение к индексу производится по заданному константному значению
• func, если значение, по которому производится обращение к индексу, является результатом функции.
В остальных случаях поле принимает значение null;
Результат EXPLAINrows - число строк, которые 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 where c2>1 and c22<20) id: 2select_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 GROUP BY STATE;
Профилирование
Сортировкаможет использовать индекс:• левый префикс, если нет where, join• если join, то только столбцы из 1ой таблицы• сортировка в одном направленииORDER BY rand()GROUP BY x ORDER BY nullORDER BY id LIMIT 10000, 10
пример продолжение
ORDER BY + LIMIT
ORDER BY + LIMIT
Сортировка
Неравенстваselect .. where A<10 and B<20 and C=5;секционирование(C,A) или (C,B)исключить одно из условий
Улучшения EXPLAIN EXPLAIN для INSERT/UPDATE/DELETE SHOW EXPLAIN JSON формат для EXPLAINANALYZE statement..
SHOW EXPLAINshow processlist;SHOW EXPLAIN FOR <thread_id>;show warnings; -- показывает запросвозможность сохранить в лог медленных запросов[mysqld] log-slow-verbosity=query_plan,explain
EXPLAIN format=json
Спасибо за вниманиевопросы / ответыSQLinfo.ru/forum/