Сводка SQL Server против множественного объединения - PullRequest
28 голосов
/ 16 сентября 2011

Что более эффективно использовать в SQL Server 2005: PIVOT или MULTIPLE JOIN?

Например, я получил этот запрос, используя два объединения:

SELECT p.name, pc1.code as code1, pc2.code as code2
FROM product p
    INNER JOIN product_code pc1
    ON p.product_id=pc1.product_id AND pc1.type=1
    INNER JOIN product_code pc2
    ON p.product_id=pc2.product_id AND pc2.type=2

Я могу сделать то же самое, используя PIVOT:

SELECT name, [1] as code1, [2] as code2
FROM (
    SELECT p.name, pc.type, pc.code
    FROM product p
        INNER JOIN product_code pc
        ON p.product_id=pc.product_id
    WHERE pc.type IN (1,2)) prods1
PIVOT(
    MAX(code) FOR type IN ([1], [2])) prods2

Какой из них будет более эффективным?

Ответы [ 2 ]

30 голосов
/ 16 сентября 2011

Ответ, конечно, будет "это зависит", но на основе тестирования этого конца ...

Предполагая

  1. 1 миллион продуктов
  2. product имеет кластерный индекс на product_id
  3. Большинство (если не все) продукты имеют соответствующую информацию в таблице product_code
  4. Идеальные индексы присутствуют на product_code для обоих запросов.

Версия PIVOT в идеале нуждается в индексе product_code(product_id, type) INCLUDE (code), тогда как версия JOIN в идеале нуждается в индексе product_code(type,product_id) INCLUDE (code)

Если они есть, указав приведенные ниже планы

Plans

тогда версия JOIN более эффективна.

В случае, если type 1 и type 2 являются единственными types в таблице, тогда версия PIVOT слегка имеет преимущество в плане числа операций чтения, поскольку ей не нужно искать в product_code вдвое, но это больше, чем перевешивает дополнительные издержки оператора объединения потоков

PIVOT

Table 'product_code'. Scan count 1, logical reads 10467
Table 'product'. Scan count 1, logical reads 4750
   CPU time = 3297 ms,  elapsed time = 3260 ms.

JOIN

Table 'product_code'. Scan count 2, logical reads 10471
Table 'product'. Scan count 1, logical reads 4750
   CPU time = 1906 ms,  elapsed time = 1866 ms.

Если есть дополнительные type записи, отличные от 1 и 2, версия JOIN увеличит свое преимущество, поскольку она просто объединяет объединения в соответствующих разделах индекса type,product_id, тогда как PIVOT В плане используется product_id, type, поэтому придется сканировать дополнительные строки type, которые смешаны со строками 1 и 2.

5 голосов
/ 16 сентября 2011

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

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

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