Использование оператора NOT IN в MySQL: синтаксис и альтернативы

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Ситуации, где NOT IN используется в запросах с NULL, приводят к сложностям. Чтобы их избежать, применим NOT EXISTS:

SQL
Скопировать код
SELECT * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t1.id = t2.ref_id); -- Исключаем несоответствующие значения!

Либо мы можем применить LEFT JOIN, усовершенствовав его с помощью проверки на IS NULL. Это может улучшить производительность при работе с большими объёмами данных:

SQL
Скопировать код
SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.id = t2.ref_id WHERE t2.ref_id IS NULL; -- Пропускаем непривязанные записи!

Для оптимальной работы с запросами используйте подход, который одновременно прочен перед NULL и обеспечивает высокую производительность.

Кинга Идем в IT: пошаговый план для смены профессии

Как сделать работу NOT IN эффективной

NOT IN становится полезным, когда: – Небольшое количество записей: NOT IN эффективен при работы с узкими списками. – Упрощение синтаксиса: Меньше строк кода и большая читаемость — это намного удобнее! – Совместимость со старыми системами: Особенно это актуально для систем, где NOT IN часто используется.

Главное правило использования — исключить NULL в вашем подзапросе для предотвращения возможных ошибок:

SQL
Скопировать код
SELECT * FROM users WHERE email NOT IN (SELECT email FROM unsubscribed_users WHERE email IS NOT NULL); -- Отправляем приглашения только на подтверждённые email!

За пределами NOT IN: расширенный синтаксис

Эффективность с LEFT JOIN / IS NULL

LEFT JOIN / IS NULL — это гарантированный способ замены NOT IN, исключающий полное сканирование таблиц и, следовательно, позволяющий экономить ресурсы. MySQL автоматически преобразует такие запросы в NESTED LOOPS ANTI JOIN, ускоряя выполнение.

Пример запроса для исключения несоответствующих данных:

SQL
Скопировать код
SELECT t1.column1, t1.column2 FROM table1 t1
LEFT JOIN table2 t2 ON t1.matching_column = t2.matching_column
WHERE t2.matching_column IS NULL; -- Исключаем несовпадающие записи.

Надёжность NOT EXISTS

Использование NOT EXISTS оберегает от NULL значений, которые могут непредсказуемо влиять на результаты, применяемые в NOT IN.

Пример такого запроса:

SQL
Скопировать код
SELECT column1, column2 FROM table1 t1
WHERE NOT EXISTS (
  SELECT 1 FROM table2 t2 WHERE t1.matching_column = t2.matching_column
); -- Оставляем только соответствующие записи.

Предохранитесь от ошибок! Работа с версиями и синтаксисом

Важно своевременно обновляться до последней версии MySQL и жестко следить за корректностью синтаксиса. Современные версии часто содержат специальные оптимизации, о существовании которых вы, возможно, даже не подозреваете.

Многотабличные проверки

Если вы хотите использовать пакетные проверки на основе нескольких списков, распространите множественные LEFT JOIN и последующую проверку на IS NULL:

SQL
Скопировать код
SELECT t1.*
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.ref_id
LEFT JOIN table3 t3 ON t1.id = t3.ref_id
WHERE t2.ref_id IS NULL AND t3.ref_id IS NULL; -- Массовое исключение несоответствующих записей.

Визуализация

Представим задачу: нужно избежать приглашения нежелательных гостей на мероприятие.

Мы имеем список приглашённых (👥): [Алиса, Боб, Чарли] И список неприглашённых (🚫): [Боб, Дэйв]

Реализуем запрос NOT IN: проверяем, кого из гостей не стоит приглашать?

SQL
Скопировать код
SELECT name FROM group_a WHERE name NOT IN (SELECT name FROM group_b);

Получаем результат — гости, которых мы пригласим:

👥➖🚫: [Алиса, Чарли]

'NOT IN' исключает 'Боба'. Боб, прости!

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Предотвращение проблем с NULL в NOT IN

NULL значения могут вызвать непредвиденные ситуации при работе с NOT IN. Поэтому всегда предусматривайте исключение NULL из подзапросов:

SQL
Скопировать код
SELECT fruit FROM basket WHERE fruit NOT IN (SELECT fruit FROM rotten_fruit WHERE fruit IS NOT NULL);

Ошибки, промахи и недочёты

NOT IN в запросах, включающих некачественно разработанные подзапросы, может привести к некорректным результатам. Избегайте использования NULL значений и всегда тестируйте код для проверки точности условий — это гарантирует корректную работу вашей базы данных.

Рекомендации для эффективной работы

  • EXPLAIN: Инструмент помогающий понять, какой механизм работы лежит в основе запроса.
  • Индексы: Они ускоряют выполнение запросов, подобно обслуживанию официантов.
  • Отслеживайте состояние базы данных: Анализируйте статистику и данные для оптимального управления запросами.

Полезные материалы

  1. Понимание влияния NOT IN в SQL-запросах — Обсуждение NOT IN против NOT EXISTS на Stack Overflow.
  2. MySQL :: MySQL 8.0 Справочник по оптимизации субзапросов — Руководство по оптимизации субзапросов от MySQL.
  3. Использование NOT EXISTS в MySQL — Преимущества NOT EXISTS по сравнению с NOT IN в MySQL.
  4. Улучшение производительности SQL Server — Как избежать использования функций в условии WHERE для увеличения производительности в SQL Server.
  5. Обсуждение проблем MySQL NOT IN — Вы можете задать свой вопрос о NOT IN на Stack Overflow.