Являются ли несвязанные результирующие наборы более производительными, чем запрос с объединениями при использовании с предложением IN? - PullRequest
0 голосов
/ 21 июля 2011

Имея подзапрос в предложении IN, лучше ли мне возвращать большое количество результатов (более 10000 строк) или использовать объединения таблиц для ограничения результатов?

Например:

select * from Units u
  inner join pm_Properties p on p.PropertyId = u.PropertyId
  where p.State = 'CA'
  and u.UnitId in (select UnitId from Leases l where l.IsActive = 1)

против

select * from Units u
  inner join pm_Properties p on p.PropertyId = u.PropertyId
  where p.State = 'CA'
  and u.UnitId in (select UnitId from Leases l 
    inner join Units u on u.UnitId = l.UnitId 
    inner join Properties p on p.PropertyId = u.PropertyId 
    where l.IsActive = 1 and p.State = 'CA')

В обоих случаях я хочу вернуть результаты, объединенные со свойствами.Мне просто интересно узнать разницу в производительности оператора IN.Кроме того, если это имеет значение, сервером является MS SQL 2008 R2.

Ответы [ 3 ]

2 голосов
/ 21 июля 2011

Используйте первый (если у вас нет проблем с производительностью по какой-либо причине).

Второй - просто предоставление избыточной информации, которую SQL-сервер сможет обработать для себя - все, что вы сделали, - это усложнили запрос, увеличив стоимость разработки плана выполнения и повысив шансы на его выигрыш. Не могу найти оптимальный план.

0 голосов
/ 21 июля 2011

Как и предполагал JNK, это зависит.

Это зависит от того, насколько сложными должны быть ваши условия соединения, и сколько строк в каждой таблице имеет относительно других таблиц. Я думаю, что в «нормальной» ситуации ваш первый пример без объединений внутри предложения IN будет быстрее, но это будет зависеть от факторов, которые я упомянул.

Итак, если вы действительно пытаетесь абсолютно оптимизировать производительность, я бы протестировал их обоих и включил в производство то, что лучше для вашей конкретной ситуации. Но, если бы они были даже близко, я бы предпочел первый (который, я думаю, в любом случае победит в большинстве случаев). Оптимизатору легче работать и, что еще важнее, легче читать, что означает, что его будет проще поддерживать.

0 голосов
/ 21 июля 2011

Я думаю, что наиболее эффективный способ позволить оптимизатору выполнять свою работу - избегать обеих версий с подзапросами.Почему бы не это?

SELECT * 
  FROM Units AS u
  INNER JOIN pm_Properties AS p
  ON p.PropertyId = u.PropertyId
  INNER JOIN Leases AS l
  ON l.UnitId = u.UnitId
  AND l.IsActive = 1
  WHERE p.State = 'CA';

Основываясь на предложении JNK, еще одна альтернатива заключается в следующем (но, как я предположил, может быть много проверок ввода-вывода на предмет действительной аренды, если существует большой процентне в CA):

SELECT *
    FROM Units AS u
    INNER JOIN pm_Properties AS p
    ON p.PropertyId = u.PropertyId
    WHERE p.State = 'CA'
    AND EXISTS
    (
      SELECT 1 FROM Leases AS l
         WHERE l.UnitId = u.UnitId
         AND l.IsActive = 1
    );

Конечно, вы знаете свои данные, свои индексы, свое оборудование, свои схемы использования и т. д. самый эффективный способ определить, какой маршрут вы используете.Лучше всего проверить их самостоятельно - это даст вам более надежный ответ, чем любой, кого вы можете спросить здесь.Никому не в обиду, но есть слишком много переменных, чтобы можно было сделать общее утверждение.

Кроме того - и это всего лишь пустяк - какой смысл создавать псевдоним таблицы Units -> unit?Вы набрали 4 дополнительных символа, чтобы избежать ввода одного - что может иметь смысл, если вы планируете ссылаться на Units более 4 раз в запросе, но особенно в этом случае я бы предпочел сделать более короткий псевдоним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...