wtorek, 19 sierpnia 2014

T-SQL: Tabele tymczasowe, zmienne typu TABLE, różnice

Język T-SQL umożliwia tworzenie tabel tymczasowych oraz zmiennych typu TABLE.

Tabele tymczasowe dzielimy na:

#lokalne - do których dostęp posiadamy w ramach otwartej sesji

##globalne - dostępne w ramach SERWERA (czyli będzie ona dostępna również w ramach innej bazy).

@zmienne typu TABLE - dostępne od chwili wywołania do zakończenia działania skryptu

Pierwsza różnica pomiędzy tabelami tymczasowymi a zmiennymi: tabele tymczasowe TWORZYMY, a zmienne DEKLARUJEMY.

Składnia tworzenia tabel tymczasowych:

CREATE TABLE #NAZWA_TABELI
(
kolumna1   typ,
kolumna2   typ,
...
kolumnaN, typ )

warto też pamiętać, że możemy od razu przekazać dane z zapytania do tabeli tymczasowej, bez konieczności podawania jej definicji, dodając przed FROM magiczne "INTO #TABELA", np

CREATE TABLE #TEMP 
(
NAME NVARCHAR(100) 
)
SELECT
name, surname, age

FROM PERSON

możemy zastąpić

SELECT
name, surname, age
INTO #TEMP
FROM PERSON


Wówczas tabela tymczasowa utworzy się sama, a jej kolumny będą odpowiadały nazwom kolumn zwracanych przez kwerendę. Należy wówczas pamiętać o dwóch podstawowych zasadach:
  1. Wszystkie zwracane kolumny w kwerendzie muszą posiadać nazwy
  2. Nazwy kolumn muszą być unikatowe (nie mogą się powtórzyć)



W przypadku deklarowania zmiennej typu TABLE:

DECLARE @NAZWA_TABELI TABLE
(
kolumna1   typ,
kolumna2   typ,
...
kolumnaN, typ
)

Zastosowanie

Zapewne niejednokrotnie pojawiała się potrzeba tworzenia tabel "na chwilę". Możemy oczywiście tworzyć pewne tabele, nazwać je "tymczasowe" i wierzyć, że kiedyś je usuniemy :) Niemniej jednak takie rozwiązanie jest mało eleganckie, niejednokrotnie później pozostają dziwne byty, których boimy się usunąć, a które w rzeczywistości utworzyliśmy na 5 minut...

Tabele tymczasowe wprost świetnie nadają się do importów i migracji danych pomiędzy środowiskami oraz analizy danych, gdzie operujemy już na jednym, stałym, wstępnie ograniczonym "wiaderku danych", do których możemy co jakiś czas później się ponownie odwołać.


Zmienne natomiast mają dość krótki żywot (do zakończenia działania skryptu) :) Niemniej jednak są w teorii bardziej wydajne, ponieważ w przypadku SQL SERVER przechowywane są w pamięci operacyjnej do chwili zakończenia działania skryptu. Jeśli zaraz po wykonaniu zapytania dane nie będą nam już potrzebne, zmienna może okazać się niezłym pomysłem. Są one szczególnie fajne przy mniejszych zbiorach, np. gdy nie chcemy operować korzystać z kursorów do poruszania się po danych (a kysz!) - wówczas odpowiednia pętla po naszym "mikro zbiorze" i po krzyku.



Który rodzaj wybrać?

Zmienne typu TABLE powinniśmy stosować, gdy przekazujemy tablicę jako parametr do procedury czy funkcji. Ponadto zmienna "znika" po wykonaniu skryptu.

Przy tabelach tymczasowych powinniśmy dodatkowo pamiętać o konieczności ich usunięcia, gdy nie są już potrzebne.

Jeśli chcielibyśmy posiadać dostęp do naszej tabeli tymczasowej globalnie (np. migracja danych, głębsze analizy itd), oczywistym jest, że powinniśmy stosować ##, jednakże tylko w sytuacji, kiedy faktycznie będziemy korzystali z tabeli tymczasowej później.

Warto też pamiętać, że tabele tymczasowe możemy wykorzystać do złączeń (JOIN). Możemy dzięki temu łączyć już przefiltrowany zbiór pewnych danych z tabeli/tabel (np słowników) w formie #tabeli_tymczasowej, z głównym źródłem - praktyczne przy dużych słownikach, z których interesuje nas niewielki ich fragment.

Wydajność

Pod względem wydajności, nie istnieje uniwersalne uzasadnienie, kiedy powinniśmy korzystać z tabel tymczasowych # / ##, a kiedy ze zmiennych. W google można odnaleźć masę rankingów na temat szybkości działania.
Zmienne przechowywane są w pamięci (chyba że przekroczą określony rozmiar - wówczas trafią do tempdb), więc w teorii powinny być szybsze.
Nie przeprowadzałem wystarczającej ilości prób, aby jednoznacznie powiedzieć, kiedy stosować @, a kiedy #.

Osobiście uważam, że optymalnym rozwiązaniem będzie przetestowanie "na żywo" i po prostu - wybranie szybszego rozwiązania per-case. Osobiście wielokrotnie byłem zaskoczony rezultatem działania. Od razu przypomina mi się cudowny cytat, który kiedyś gdzieś usłyszałem:

W teorii, teoria i praktyka to to samo. 
W praktyce, tak nie jest.

4 komentarze:

  1. Tabele tymczasowe i zmienne tabelaryczne nie sa przechowywane w pamieci operacyjnej..

    OdpowiedzUsuń
  2. Zarówno tabele tymczasowe jak i zmienne tabelaryczne są zapisywane w bazie tempd, zatem na dysku. Zarówno w tabelach tymczasowych jak i zmiennych tabelarycznych można stosować złączenia.

    OdpowiedzUsuń
  3. Jak się mają do tego jeszcze wyrażenia CTE?

    OdpowiedzUsuń
  4. 58 years old Administrative Assistant IV Sigismond Royds, hailing from Smith-Ennismore-Lakefield enjoys watching movies like Mystery of the 13th Guest and Inline skating. Took a trip to Himeji-jo and drives a Ferrari 250 GT SWB Berlinetta Competizione. Wiecej Bonusow

    OdpowiedzUsuń