@IdFox

Как оптимизировать SQL запрос?

Всем привет

Подскажите, нужно ли оптимизировать SQL запрос в плане нагрузки на сервер?
Или он нормально составлен и так и должен выполняться?

Имеем две таблички
numbers - например список телефонных номеров
numbers_type - категории, присвоенные каждому номеру (их может быть несколько)

Задача
Выбрать из numbers номера с определенными категориями (несколько)
Пишем запрос

SELECT * FROM `numbers` WHERE `number` IN (
SELECT `number` FROM `numbers_type` WHERE `type` IN (1, 3, 5)
)

У меня вопрос
Вложенный запрос возвращает большое количество записей
Ну например 50 000 шт
Потом эта результирующая выборка попадает в основной запрос
Не знаю как правильно сказать - MySQL это нормально переваривает?
Или лучше как-то сделать другую структуру табличек, чтобы запрос легче выполнялся для сервера

Спасибо за ответы
  • Вопрос задан
  • 3044 просмотра
Решения вопроса 1
yellow79
@yellow79
Senior Software Engineer
Мне кажется у вас тут будет лучше работать JOIN
SELECT 
	*
FROM 
	`numbers` A 
	LEFT JOIN `numbers_type` B ON A.`number` = B.`number` 
WHERE 
	B.`type` IN (1, 3, 5)
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
alex-1917
@alex-1917
Если ответ помог, отметь решением
50к - мизерная выборка, забей!!))
если проект на вырост, тогда не забивай!!))

В твоем варианте смешная выборка, не видел ты 10 этажных джойнов, коллега!!...

И еще - не забывай, что БД ВСЕГДА хранится на диске, а в памяти она появляется уже потом)))! отсюда выход для некоторых огромных запросов - быстрее вопрос решается обработкой не в БД, а на приложении.
Если кратко, то делаешь выборку ВСЕХ твоих номеров без условий - для БД это самая непрожорливая операция, по сути два мгновения, далее выборку в массив и уже на сервере разбираешь чо и как, через тот же php. Проверено на выборках 20М-300М - - скорость фильтрации на два порядка больше, если это дело поручать приложению!
Ответ написан
Комментировать
@Barmunk
Как насчет join? То что у вас очень странно выглядит.

50 тысяч это не много.
in имеет лимиты https://stackoverflow.com/questions/1069415/limit-...
Ответ написан
Комментировать
dimonchik2013
@dimonchik2013
non progredi est regredi
когда ты делаешь join
по проиндексированным полям, разумеется
мускуль бежит по строкам (а на диске таблица - это обычный бинарный файл) банальным сравнением строк (кури алгоритмы если надо) - считай, самой быстрой операцией, и вносит в память все подходящие (поэтому нужно select не * а конкретные поля - меньше данных, меньше висит в памяти)
при этом индексы убирают необходимость прохода по заведомо несовпадающим строкам

когда юзаешь where in - то результат IN мускулю тоже приходится держать в памяти, но прочекать при этом придется минимум только те что в where, а при неудачном оптимизаторе - всю таблицу, а при очень неудачном - еще и не один раз

проще говоря, "where in" всегда медленнее join, по сути - это синтаксический сахар для разовых запросов
если и кажется быстрее, то на небольших сетах, где на join больше накладных расходов
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы