Чтение планов выполнения и оптимизация запросов
Посмотрите, как MySQL на самом деле выполняет ваш запрос, и перепишите его так, чтобы он работал быстро
Главная идея:
SELECT - это запрос, а не рецепт. Вы описываете, какие строки хотите получить; оптимизатор запросов решает, как их достать - какой индекс прочитать, сканировать или искать по индексу и в каком порядке соединять таблицы. EXPLAIN показывает этот план до выполнения; EXPLAIN ANALYZE выполняет запрос и сообщает, что произошло на самом деле. Как только вы научитесь их читать, исправление большинства медленных запросов становится очевидным.
К концу вы сможете:
- читать ключевые столбцы
EXPLAIN:type,key,rows,filtered,Extra, - отличать полное сканирование таблицы от сканирования диапазона по индексу или однострочного поиска,
- распознавать основные стратегии соединения - вложенные циклы и хеш-соединение,
- с помощью
EXPLAIN ANALYZEсравнивать оценочное и фактическое число строк, - находить и исправлять классические шаблоны медленных запросов.
0. Пример схемы
Все запросы ниже работают с одной небольшой базой данных магазина. Создайте её один раз и держите в уме до конца темы.
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(80),
city VARCHAR(60),
created_at DATE
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
status VARCHAR(20),
total DECIMAL(10,2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
INSERT INTO customers VALUES
(1,'Aida','Bishkek','2023-02-10'),
(2,'Bekturs','Osh','2023-05-01'),
(3,'Cholpon','Bishkek','2024-01-20');
INSERT INTO orders VALUES
(10,1,'2024-03-01','paid', 120.00),
(11,1,'2024-03-04','paid', 55.50),
(12,2,'2024-03-04','pending', 80.00),
(13,3,'2024-04-11','paid', 210.00);
Считайте, что в продакшене обе таблицы гораздо больше (миллионы заказов). Маленький пример нужен для читаемости результатов; важны именно планы при большом масштабе.