SQL CASE против эффективности JOIN - PullRequest
7 голосов
/ 16 июня 2009

В моей базе данных MS SQL Server я извлекаю данные транзакций на основе различных кодов, которые находятся в одном столбце.

Было бы эффективнее:

  • объединять одну и ту же таблицу снова и снова для каждого кода в предложении WHERE

  • сделать несколько операторов регистра для всей таблицы (показано ниже)

  • делает несколько операторов регистра для всей таблицы, но ограничивает ее WHERE SubsidCde IN ('AA','BA','BB', etc) предложением

У нас так много запросов в секунду, что, несмотря на то, что я попробовал все 3 метода, я не получил окончательных результатов.

SELECT
    SUM(CASE WHEN Subsid_Cde = 'AA' THEN Trans_Amt END),0) [AA],
    SUM(CASE WHEN Subsid_Cde = 'BA' THEN Trans_Amt END),0) [BA],
    SUM(CASE WHEN Subsid_Cde = 'BB' THEN Trans_Amt END),0) [BB]
FROM
    Transactions

--  There are 8 more rows like this, using a different code for each line

Ответы [ 3 ]

4 голосов
/ 16 июня 2009

Если вы суммируете все возможные (или большинство) значений поля Subsid_Cde, то CASE работает быстрее, так как не будет сканировать таблицу несколько раз, так как суммирует суммы. Если вы ищете только небольшое подмножество возможных полей Subsid_Cde, то отдельные операции выбора / объединения (вместе с индексом для Subsid_Cde) будут работать быстрее.

Вам нужно научиться читать Планы выполнения, тогда вы сможете сами придумывать такие вещи.

Также, в качестве альтернативы, вы можете выполнить GROUP BY для Subsid_Cde, заключенного в предложение PIVOT (Google для PIVOT MS SQL SERVER 2005)

2 голосов
/ 16 июня 2009

3 - ваша лучшая ставка. Его легко читать, позже его легко изменить, и он должен использовать индексы, которые вы определили, и которые вы планируете использовать (все же, проверьте).

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

- 2 Таблицы транзакций имеют тенденцию расти очень большими, поэтому вам НИКОГДА не захочется сканировать всю таблицу. Так что # 2 определенно отсутствует, если только коды, которые вы будете использовать в своем запросе, не вернут вам все строки в любом случае.

1 голос
/ 16 июня 2009

Используйте это:

SELECT  (
        SELECT  SUM(Trans_Amt)
        FROM    Transactions
        WHERE   Subsid_Cde = 'AA'
        ) AS sum_aa,
        (
        SELECT  SUM(Trans_Amt)
        FROM    Transactions
        WHERE   Subsid_Cde = 'BB'
        ) AS sum_bb

, без внешнего предложения FROM или WHERE.

В SQL Server 2005+ используйте это:

SELECT  [AA], [BB]
FROM    (
        SELECT  trans_amt, subsid_cde
        FROM    transactions
        ) q
PIVOT   (
        SUM(trans_amt)
        FOR subsid_cde IN (['AA'], ['BB'])
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...