Jaka jest różnica między Common Table Expression (CTE) a tabelą tymczasową? A kiedy powinienem używać jednego na drugim?
CTE
WITH cte (Column1, Column2, Column3)
AS
(
SELECT Column1, Column2, Column3
FROM SomeTable
)
SELECT * FROM cte
Tabela temperatur
SELECT Column1, Column2, Column3
INTO #tmpTable
FROM SomeTable
SELECT * FROM #tmpTable
sql-server
cte
Rachel
źródło
źródło
Odpowiedzi:
Jest to dość ogólne, ale dam ci tak ogólną odpowiedź, jak tylko potrafię.
CTE ...
VIEW
s# Tabele temperatur ...
Jeśli chodzi o to, kiedy z nich korzystać, mają one bardzo różne przypadki użycia. Jeśli będziesz mieć bardzo duży zestaw wyników lub będziesz musiał odwoływać się do niego więcej niż jeden raz, umieść go w
#temp
tabeli. Jeśli wymaga rekurencji, jest jednorazowego użytku lub po prostu upraszcza coś logicznie,CTE
preferowane jest a .Ponadto,
CTE
powinny nigdy być wykorzystywane do realizacji . Prawie nigdy nie przyspieszysz korzystania z CTE, ponieważ znowu jest to tylko widok jednorazowy. Możesz robić z nimi porządne rzeczy, ale przyspieszenie zapytania nie jest tak naprawdę jedną z nich.źródło
EDYTOWAĆ:
Zobacz komentarze Martina poniżej:
Oryginalna odpowiedź
CTE
Przeczytaj więcej na MSDN
CTE tworzy tabelę używaną w pamięci, ale jest poprawna tylko dla określonego zapytania po niej. Podczas korzystania z rekurencji może to być efektywna struktura.
Możesz również rozważyć użycie zmiennej tabeli. Jest to używane, ponieważ używana jest tabela tymczasowa i może być używana wiele razy, bez potrzeby ponownego zmaterializowania dla każdego połączenia. Ponadto, jeśli musisz teraz zachować kilka rekordów, dodaj kilka kolejnych rekordów po kolejnym wyborze, dodaj jeszcze kilka rekordów po kolejnej operacji, a następnie zwróć tylko garść rekordów, to może być przydatna struktura, ponieważ nie trzeba go upuszczać po wykonaniu. Głównie tylko cukier syntaktyczny. Jeśli jednak utrzymasz niską liczbę wierszy, nigdy nie pojawi się ona na dysku. Zobacz Jaka jest różnica między tabelą tymczasową a zmienną tabelową w programie SQL Server? po więcej szczegółów.
Tabela temperatur
Przeczytaj więcej na MSDN - Przewiń w dół o około 40%
Tabela tymczasowa to dosłownie tabela utworzona na dysku, tylko w określonej bazie danych, o której wszyscy wiedzą, że można ją usunąć. Dobry deweloper jest odpowiedzialny za zniszczenie tych tabel, gdy nie są już potrzebne, ale DBA może je również wyczyścić.
Stoły tymczasowe występują w dwóch odmianach: lokalnej i globalnej. W odniesieniu do MS Sql Server używasz
#tableName
oznaczenia lokalnego i##tableName
globalnego (zwróć uwagę na użycie pojedynczego lub podwójnego # jako cechy identyfikującej).Zauważ, że w przypadku tabel tymczasowych, w przeciwieństwie do zmiennych tabel lub CTE, możesz zastosować indeksy i tym podobne, ponieważ są to legalne tabele w normalnym znaczeniu tego słowa.
Zasadniczo korzystałbym z tabel tymczasowych dla dłuższych lub większych zapytań oraz zmiennych CTE lub zmiennych tabel, gdybym miał już mały zestaw danych i chciałem po prostu szybko napisać trochę kodu dla czegoś małego. Doświadczenie i porady innych wskazują, że powinieneś używać CTE tam, gdzie zwracana jest niewielka liczba wierszy. Jeśli masz dużą liczbę, prawdopodobnie skorzystasz z możliwości indeksowania w tabeli tymczasowej.
źródło
SELECT Column1, Column2, Column3 FROM SomeTable
WITH T(X) AS (SELECT NEWID())SELECT * FROM T T1 JOIN T T2 ON T1.X=T2.X
, sprawdź także plany wykonania. Chociaż czasami można zhakować plan, aby uzyskać szpulę. Istnieje element połączeniowy z prośbą o podpowiedź.Zaakceptowane odpowiedź tu mówi „CTE nigdy nie powinny być wykorzystywane do realizacji” - ale które mogłyby wprowadzać w błąd. W kontekście tabel CTE kontra tabele tymczasowe właśnie skończyłem usuwać zbędne śmieci z zestawu przechowywanych proc, ponieważ niektórzy doofus musieli myśleć, że użycie tabel tymczasowych jest niewielkie lub wcale. Wrzuciłem wiele do CTE, z wyjątkiem tych, które zgodnie z prawem miały być ponownie wykorzystane podczas całego procesu. Zyskałem około 20% wydajności według wszystkich wskaźników. Następnie przystąpiłem do usuwania wszystkich kursorów, które próbowały zaimplementować przetwarzanie rekurencyjne. To tam widziałem największy zysk. Ostatecznie zmniejszyłem czasy reakcji dziesięciokrotnie.
CTE i tabele tymczasowe mają bardzo różne przypadki użycia. Chciałbym tylko podkreślić, że chociaż nie jest to panaceum, zrozumienie i poprawne użycie CTE może prowadzić do naprawdę naprawdę doskonałej poprawy zarówno jakości / obsługi kodu, jak i szybkości. Odkąd je opanowałem, uważam tabele tymczasowe i kursory za wielkie zło przetwarzania SQL. Mogę teraz sobie poradzić ze zmiennymi tabel i współczynnikami CTE dla prawie wszystkiego teraz. Mój kod jest czystszy i szybszy.
źródło
CTE może być wywoływany wielokrotnie w zapytaniu i jest oceniany za każdym razem, gdy się do niego odwołuje - proces ten może być rekurencyjny. Jeśli zostanie tylko raz odesłany, zachowuje się podobnie do zapytania podrzędnego, chociaż parametry CTE można sparametryzować.
Tabela tymczasowa jest utrwalana fizycznie i może być indeksowana. W praktyce optymalizator zapytań może również zachowywać wyniki pośrednich połączeń lub zapytań za scenami, na przykład w operacjach buforowania, więc nie jest prawdą, że wyniki CTE nigdy nie są utrwalane na dysku.
Z drugiej strony zmienne tabeli IIRC są zawsze strukturami w pamięci.
źródło
Tabela temp jest prawdziwym obiektem w tempdb, ale cte jest tylko rodzajem otulenia złożonego zapytania w celu uproszczenia składni organizacji rekurencji w jednym kroku.
źródło
Podstawowym powodem korzystania z CTE jest dostęp do funkcji okien, takich jak
row_number()
i wiele innych.Oznacza to, że możesz robić rzeczy takie jak uzyskanie pierwszego lub ostatniego wiersza na grupę BARDZO BARDZO bardzo szybko i wydajnie - bardziej efektywnie niż inne środki w większości praktycznych przypadków .
Możesz uruchomić zapytanie podobne do powyższego, używając skorelowanego podzapytania lub zapytania częściowego, ale CTE będzie szybsze w prawie wszystkich scenariuszach.
Ponadto CTE mogą naprawdę uprościć kod. Może to prowadzić do wzrostu wydajności, ponieważ lepiej rozumiesz zapytanie i możesz wprowadzić więcej logiki biznesowej, aby zoptymalizować optymalizator.
Dodatkowo, CTE mogą zwiększyć wydajność, jeśli rozumiesz logikę biznesową i wiesz, które części zapytania powinny być uruchamiane jako pierwsze - zazwyczaj stawiaj najpierw najbardziej selektywne zapytania, które prowadzą do zestawów wyników, które mogą korzystać z indeksu przy następnym łączeniu i dodaj
option(force order)
zapytanie WskazówkaWreszcie, CTE nie używają domyślnie tempdb, więc zmniejszasz rywalizację o to wąskie gardło poprzez ich użycie.
Tabel tymczasowych należy używać, jeśli trzeba wielokrotnie wysyłać zapytania do danych, lub alternatywnie, jeśli mierzy się zapytania i odkrywa się je, wstawiając do tabeli tymczasowej, a następnie dodając indeks poprawiający wydajność.
źródło
Wydaje się, że jest tu trochę negatywności w stosunku do CTE.
Rozumiem, że CTE jest taki, że jest to rodzaj doraźnego poglądu. SQL jest zarówno językiem deklaratywnym, jak i opartym na zestawie. CTE to świetny sposób na zadeklarowanie zestawu! Brak możliwości indeksowania CTE jest w rzeczywistości dobrą rzeczą, ponieważ nie jest to konieczne! To naprawdę rodzaj cukru syntaktycznego, który ułatwia odczyt / zapis zapytania. Każdy porządny optymalizator opracuje najlepszy plan dostępu, korzystając z indeksów na bazowych tabelach. Oznacza to, że możesz skutecznie przyspieszyć zapytanie CTE, postępując zgodnie ze wskazówkami dotyczącymi indeksu w bazowych tabelach.
Również dlatego, że zdefiniowałeś zestaw jako CTE, nie oznacza to, że wszystkie wiersze w zestawie muszą zostać przetworzone. W zależności od zapytania optymalizator może przetworzyć „wystarczającą” liczbę wierszy, aby spełnić zapytanie. Może potrzebujesz tylko pierwszych 20 lub więcej na ekranie. Jeśli zbudowałeś tabelę tymczasową, to naprawdę musisz czytać / pisać wszystkie te wiersze!
Na tej podstawie powiedziałbym, że CTE są świetną funkcją SQL i mogą być używane wszędzie tam, gdzie ułatwiają odczytanie zapytania. Myślałem tylko o tabeli tymczasowej dla procesu wsadowego, który naprawdę musiałby przetworzyć każdy rekord. Nawet wtedy nie jest to zalecane, ponieważ w tabeli tymczasowej bazy danych jest znacznie trudniej pomóc w buforowaniu i indeksach. Lepiej mieć stały stół z polem PK unikatowym dla Twojej transakcji.
Muszę przyznać, że moje doświadczenie dotyczy głównie DB2, więc zakładam, że CTE działa w podobny sposób w obu produktach. Z chęcią stanę się poprawiony, jeśli CTE są w jakiś sposób gorsze na serwerze SQL. ;)
źródło