@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 больше накладных расходов
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
20 апр. 2024, в 14:27
3000 руб./за проект
20 апр. 2024, в 13:56
7000 руб./за проект
20 апр. 2024, в 13:52
7000 руб./за проект