2009-06-16 25 views
6

W mojej bazie danych MS SQL Server wyciągam dane transakcji na podstawie różnych kodów, które znajdują się w jednej kolumnie.SQL CASE vs JOIN efficiency

byłoby bardziej efektywne:

  • przyłączyć się do tej samej tabeli kółko dla każdego kodu w WHERE

  • zrobić wiele instrukcji sprawę na całej tabeli (poniżej)

  • zrobić wiele instrukcji case na całej tabeli, ale ogranicza go przez WHERE SubsidCde IN ('AA','BA','BB', etc) klauzuli

Mamy tak wiele zapytań działających na sekundę, że mimo że wypróbowałem wszystkie 3 metody, nie otrzymuję ostatecznych wyników.

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 
+0

Zobacz http://sqlblog.com/blogs/linchi_shea/archive/2011/04/04/performance-impact-the-cost-of-doing-small-lookups-in-a-large-batch.aspx –

Odpowiedz

3

Jeśli zsumowanie wszystkich możliwych (lub większość) wartości pola Subsid_Cde, następnie CASE jest szybsze, gdyż nie przejrzy tabelę wiele razy, jak to agreguje sumy. Jeśli szukasz tylko niewielkiego podzbioru możliwych pól Subsid_Cde, wówczas oddzielne selekcje/łączenia (wraz z indeksem na Subsid_Cde) będą działały szybciej.

Musisz nauczyć się odczytywać Plany Wykonania, wtedy będziesz w stanie wymyślić takie rzeczy samodzielnie.

też, alternatywnie, można zrobić GROUP BY na Subsid_Cde zawinięte w klauzuli PIVOT (google dla PIVOT MS SQL Server 2005)

1

Użyj tego:

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 

, bez zewnętrznego FROM lub WHERE klauzuli.

W SQL Server 2005+, użyj tego:

SELECT [AA], [BB] 
FROM (
     SELECT trans_amt, subsid_cde 
     FROM transactions 
     ) q 
PIVOT (
     SUM(trans_amt) 
     FOR subsid_cde IN (['AA'], ['BB']) 
     ) 
2

3 jest najlepszym. Jest łatwy do odczytania, można go później łatwo modyfikować i powinien korzystać z indeksów, które zdefiniowałeś i których spodziewasz się używać (nadal, sprawdź).

- 1 Czasami trzeba dołączyć do tego samego stołu. Ale to nie jest jedna z nich i dołączenie za każdym razem, gdy trzeba włączyć nowy Subsid_Cde sprawia, że ​​SQL jest mniej czytelny, bez faktycznego zdobywania czegokolwiek.

- 2 Tabele transakcji mają tendencję do wzrostu bardzo dużego, więc NIGDY nie chcesz przeskanować całego stołu. WięC# 2 jest zdecydowanie na zewnątrz, chyba że kody, które będziesz używał w zapytaniu, zwrócą ci wszystkie wiersze.