1 подписчик
Сегодня оптимизируем один запрос.
Имеем таблицу справочник товаров (spr_tovar) на 160 000 строк .
Нам надо выбрать из неё все позиции где в названии встречается слово "телевизор"
Имеем простой запрос:
select NAME, kod_tovar, id
from spr_tovar
where NAME like '%телевизор%'
ORDER BY NAME
Этот запрос выполняется 20 секунд!!!
Причем если строка поиска будет короткая('%т%', '%те%', '%тел%') еще сносно ищет
Первый эксперт скажет: Да у тебя комп медленный
- нет это сервер на ssd и с большим количеством ядер и оперативной памяти.
Второй эксперт скажет: Да у тебя индексов нет
- Есть уникальный индекс по колонке NAME. Но он нам не поможет потому-что первый символ '%'
Третий эксперт скажет: Проблема в ORDER BY! индекс не работает если сортировка ORDER BY делается, при использовании непоследовательных частей ключа
Опытным путем выяснили что если убрать ORDER BY NAME то время выполнения: 0.5423 сек.
но почему этот запрос возвращает 15 позиций и на их сортировку требуется 20 секунд !!!?
Логично предположить что Mysql сначала сортирует потом делает like
было решено сделать сортировку уже для подзапроса
select * from (
select NAME, kod_tovar, id
from spr_tovar
where NAME like '%телевизор%' ) as t
ORDER BY NAME
и о чудо наш запрос выполняется 0.5988 сек.
чуть позже рядом с уникальным индексом по полю name добавили первичный ключ(PRIMARY KEY) по полю name
после этого запрос
select NAME, kod_tovar, id
from spr_tovar
where NAME like '%телевизор%'
ORDER BY NAME
выполняется 0.5379 сек.
Говорят первичный ключ это кластеризованный индекс в отличии от уникального
И строки данных в таблице хранятся в порядке сортировки только в том случае, если таблица содержит кластеризованный индекс.
Все равно остался вопрос:
Разве mysql так глуп что не может отсортировать строки после выполнения основного запроса?
Есть что добавить? Пишите в комментарии
1 минута
15 февраля 2023