theory_03__EXPLAIN.md
← К репозиторию занятия · 11__INDEXES/theory_03__EXPLAIN.md
EXPLAIN
EXPLAIN — это команда в MySQL, которая показывает, как оптимизатор запросов планирует выполнить заданный SQL-запрос. Она предоставляет информацию о порядке чтения таблиц, используемых индексах, методах доступа к данным и других деталях выполнения.
Основные цели EXPLAIN:
- Позволяет понять, какие индексы используются.
- Показывает тип соединения таблиц (JOIN).
- Оценивает, сколько строк будет обработано.
- Помогает оптимизировать запросы для повышения производительности.
Примеры использования:
1. Точный поиск
Запрос:
EXPLAIN SELECT * FROM big_table WHERE age = 30;
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra ---|--------------|-----------|---------------|------|---------------|------------|---------|-------|--------|----------|------------------ 1 | SIMPLE | big_table | NULL | ref | idx_age | idx_age | 5 | const | 272118 | 100.00 | Using index
Расшифровка по полям:
| Поле | Значение | Описание |
|---|---|---|
| id | 1 | Идентификатор запроса. Если бы были подзапросы или UNION, здесь были бы другие значения. |
| select\_type | SIMPLE | Простой SELECT без подзапросов. |
| table | big\_table | Имя таблицы, к которой выполняется доступ. |
| partitions | NULL | Партиции - глубокий (низкоуровневый) механизм разбиения больших таблиц для ускорения поиска. Здесь не используются. |
| type | ref | Хороший тип доступа. MySQL использует индекс с точным сравнением (например, WHERE age = 30). |
| possible\_keys | idx\_age | Возможные индексы, которые MySQL может использовать. |
| key | idx\_age | Фактически выбранный индекс. |
| key\_len | 5 | Длина используемой части индекса. Например, для INT это 4 байта + 1 служебный байт. |
| ref | const | Значение, с которым сравнивается поле (например, age = 30). |
| rows | 272118 | Примерное число строк, которые нужно просмотреть. Это оценка на основе статистики. |
| filtered | 100.00 | Ожидаемый процент строк, прошедших фильтр. 100% — хорошо. |
| Extra | Using index | Используется покрывающий индекс — все нужные данные берутся из индекса, доступ к таблице не требуется. |
Что это значит:
type = ref говорит о том, что используется точный поиск по индексу (это гораздо лучше, чем ALL или range в ряде случаев).
key = idx_age подтверждает, что используется индекс.
ref = const означает, что значение (например, age = 30) заранее известно.
rows = 272118 говорит о том, что MySQL ожидает около 272 тысяч совпадений. Это оценка, а не точное число.
Using index означает, что SELECT может быть выполнен, не заглядывая в саму таблицу — данные берутся напрямую из индекса.
Пояснение по key_len = 5:
Если поле age — это INT (4 байта), то key_len = 4 + 1 (служебный байт, например, NULL-байт) = 5.
Заключение:
Этот план эффективен, потому что:
используется индекс;
не читается вся таблица;
нет лишней фильтрации (filtered = 100%);
данные берутся из индекса напрямую (Using index);
доступ type = ref — быстрый.
2. Сравнение двух вариантов EXPLAIN для запроса с индексом idx_age (точный и диапазонный поиск)
EXPLAIN SELECT * FROM big_table WHERE age = 30;
EXPLAIN SELECT * FROM big_table WHERE age > 30;
| id | select_type | table | type | key | key_len | ref | rows | filtered | Extra | Условие |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | big_table | ref | idx_age | 5 | const | 272118 | 100.00 | Using index | age = 30 |
| 1 | SIMPLE | big_table | range | idx_age | 5 | NULL | 4972162 | 100.00 | Using where; Using index | age > 30 |
Общее пояснение
🔑 Индекс idx_age используется в обоих случаях.
📘 type = ref — это точный поиск по значению (age = 30); быстрее, так как указывает на конкретные значения.
📗 type = range — используется при условиях вида age > 30; это диапазонный поиск, охватывающий множество значений.
⏱ rows — оценка количества строк, которые MySQL должен просмотреть:
для age = 30 — меньше (272K строк),
для age > 30 — больше (почти 5 млн строк).
📄 Extra = Using index — в обоих случаях чтение идёт из индекса (покрывающий индекс).
Для age > 30 добавляется Using where — MySQL дополнительно фильтрует строки.
Вывод
Оба запроса используют индекс эффективно.
Равенство (age = ?) быстрее, потому что доступ более точный (ref).
Диапазон (age > ?) требует больше ресурсов, но всё ещё оптимизирован благодаря индексу.