Вопрос

Мне нужен совет относительно производительности выбора в MySQL.По причине, которую я не могу изменить, я не могу использовать JOIN для создания фильтра запросов, я могу только добавить еще одно предложение AND в WHERE.

В чем заключается эффективность:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

по сравнению с:

select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;

Обратите внимание, что существует относительно небольшое количество проектов с is_template = 1, и может быть большое количество проектов, где is_template <> 1.

Есть ли другой способ добиться того же результата без подвыборок, если я не могу ничего изменить, кроме фильтра и?

Это было полезно?

Решение

Я считаю, что второй более эффективен, так как требует только одного выбора, но чтобы быть уверенным, вы должны ОБЪЯСНИТЬ каждый запрос и проверить результаты.

EXPLAIN select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

EXPLAIN select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;

Другие советы

Разница между этими двумя показателями может сильно зависеть от того, что " некоторые критерии " есть и какие возможности использовать индексы он предоставляет. Но обратите внимание, что они не эквивалентны с точки зрения результатов, если есть задачи, у которых нет проектов. Второе эквивалентно этому:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id in (select id from project where project.is_template <> 1);

Я думаю, что первый может масштабироваться лучше:

Когда вы выполняете соединение, внутренне mysql создает своего рода временную таблицу, состоящую из двух таблиц, объединенных в соответствии с указанными условиями соединения. Вы не задаете условие соединения, поэтому оно создаст временную таблицу со всеми задачами, перечисленными для всех проектов. Я совершенно уверен (но проверяю с помощью инструмента объяснения), что он делает это до применения каких-либо предложений where.

Результат: если их по 10, то будет 10 * 10 строк = 100. Вы можете увидеть, как это становится больше с ростом числа. Затем он применяет where к этой временной таблице.

Напротив, подзапрос выбирает только соответствующие строки из каждой таблицы.

Но если масштабирование не является проблемой, я не думаю, что это действительно имеет значение.

Избегайте вложенных запросов, подобных чуме, в версиях MySQL < 6.0, и я сомневаюсь, что вы используете 6.0, учитывая, что он все еще находится в альфа-фазе разработки.AFAIK, оптимизатор MySQL вообще плохо обрабатывает подзапросы.Некоторая серьезная работа была проведена по обновлению оптимизатора для версии 6.0, и теперь вложенные запросы работают намного лучше, но эти изменения не коснулись серий 5.0 или 5.1.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top