Запрос производительности присоединения до или после UNION - PullRequest
4 голосов
/ 28 октября 2009

Допустим, у нас есть запрос, который по существу использует объединение для объединения двух наборов записей в 1. Теперь мне нужно продублировать записи, как правило, используя соединение. Я считаю, что вариант 1, по моему мнению, является лучшим выбором по соображениям производительности, но мне было интересно, что думают эксперты SQL Query.

По сути, я «знаю», ответ «1». Но мне также интересно, могу ли я ошибаться - есть ли какая-то сторона этого, которую я мог бы упустить?

(SQL Server) Вот мои варианты.

псевдокод

Оригинальный запрос:

Select Name, Category from t1
Union
Select Name, Category from t2

Вариант 1)

Select Name, Category from t1
Inner Join (here)
Union
Select Name, Category from t2
Same inner Join (here)

Вариант 2)

Select * from (
Select Name, Category from t1
Union
Select Name, Category from t2
) t
(Inner Join Here)

Ответы [ 4 ]

5 голосов
/ 28 октября 2009
SELECT  Name, Category
FROM    t1
JOIN    t_right
ON      right_category = category
UNION
SELECT  Name, Category
FROM    t2
JOIN    t_right
ON      right_category = category

SELECT  *
FROM    (
        SELECT  Name, Category
        FROM    t1
        UNION
        SELECT  Name, Category
        FROM    t2
        ) t
JOIN    t_right
ON      right_category = category

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

t1

Name   Category
---    ---
Apple  1


t2

Name   Category
---    ---
Apple  1

t_right

Category
---
1
1

Первый запрос вернет Apple, 1 один раз, второй запрос вернет его дважды.

С точки зрения производительности трудно сказать, какой запрос будет более эффективным, пока мы не увидим ваши данные:

  • Первый вариант может повысить эффективность за счет применения различных алгоритмов к каждому запросу.

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

Как очень грубое практическое правило, первый вариант будет более эффективным, если условие соединения является выборочным для t1 и t2, тогда как второй вариант будет более эффективным, если это не так.

Однако в простых случаях (объединение при sargable условии с несколькими значениями высокой мощности) оптимизатор SQL Server вытолкнет конкатенацию из подзапроса, чтобы она была идентична следующему запросу:

SELECT  Name, Category
FROM    t_right
CROSS APPLY
        (
        SELECT  Name, Category
        FROM    t1
        WHERE   t1.Category = t_right.category
        UNION
        SELECT  Name, Category
        FROM    t2
        WHERE   t2.Category = t_right.category
        ) t
1 голос
/ 28 октября 2009

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

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

0 голосов
/ 22 апреля 2013

В простых случаях вариант два лучше, потому что поиск индекса по таблице "(внутреннее соединение здесь)" будет выполнен за один раз.

0 голосов
/ 28 октября 2009

В качестве базовой линии я бы выбрал вариант 2, потому что - если все остальное равно (всегда есть особые случаи и исключения) - оно должно быть быстрее.

В варианте 1 вы читаете t1, затем присоединяетесь к чтению «здесь», затем читаете t2, затем присоединяетесь к другому чтению «здесь», а затем объединяете их вместе.

В варианте 2 вы читаете t2, затем читаете t2, соединяете их вместе, а затем присоединяете объединенный набор (отличный или нет, в зависимости от использования UNION ALL) к «здесь».

Другими словами, в варианте 1 вы читаете таблицу «здесь» дважды, а в варианте 2 вы читаете ее один раз. Это может быть одна строка в таблице в памяти, но это все еще чтение.

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