W SQL Server 2005 możemy tworzyć tabele tymczasowe na jeden z dwóch sposobów:
declare @tmp table (Col1 int, Col2 int);
lub
create table #tmp (Col1 int, Col2 int);
Jakie są różnice między tymi dwoma? Czytałem sprzeczne opinie na temat tego, czy @tmp nadal używa tempdb, czy też wszystko dzieje się w pamięci.
W jakich scenariuszach jedno wyprzedza drugie?
sql-server
temp-tables
table-variable
Eric Z Beard
źródło
źródło
Odpowiedzi:
Istnieje kilka różnic między tabelami tymczasowymi (#tmp) a zmiennymi tabel (@tmp), chociaż użycie tempdb nie jest jedną z nich, jak podano w linku MSDN poniżej.
Zasadniczo w przypadku małych i średnich ilości danych oraz prostych scenariuszy użycia należy używać zmiennych tabel. (Jest to zbyt szeroka wskazówka, oczywiście z wieloma wyjątkami - patrz poniżej i następujące artykuły).
Kilka punktów do rozważenia przy wyborze między nimi:
Tabele tymczasowe są prawdziwymi tabelami, więc możesz wykonywać takie czynności, jak TWORZENIE INDEKSÓW itp. Jeśli masz duże ilości danych, dla których dostęp do indeksu będzie szybszy, dobrym rozwiązaniem są tabele tymczasowe.
Zmienne tabelowe mogą mieć indeksy przy użyciu ograniczeń PRIMARY KEY lub UNIQUE. (Jeśli chcesz mieć nieunikalny indeks, po prostu uwzględnij kolumnę klucza podstawowego jako ostatnią kolumnę w unikalnym ograniczeniu. Jeśli nie masz unikalnej kolumny, możesz użyć kolumny tożsamości). SQL 2014 ma również nieunikalne indeksy .
Zmienne tabelowe nie uczestniczą w transakcjach i
SELECT
są domyślnie z nimi związaneNOLOCK
. Zachowanie transakcyjne może być bardzo pomocne, na przykład jeśli chcesz ODWRÓCIĆ w połowie procedury, wówczas zmienne tabeli wypełnione podczas tej transakcji będą nadal zapełniane!Tabele tymczasowe mogą powodować kompilację procedur przechowywanych, być może często. Zmienne tabeli nie będą.
Możesz utworzyć tabelę tymczasową za pomocą SELECT INTO, która może być szybsza do napisania (dobra w przypadku zapytań ad-hoc) i może pozwolić ci radzić sobie ze zmieniającymi się typami danych w czasie, ponieważ nie musisz z góry definiować struktury tabeli tymczasowej.
Możesz przekazać zmienne tabeli z powrotem z funkcji, co pozwala znacznie uprościć i ponownie wykorzystać logikę (np. Uczynić funkcję dzielącą ciąg znaków na tabelę wartości na dowolnym ograniczniku).
Korzystanie ze zmiennych tabel w ramach funkcji zdefiniowanych przez użytkownika umożliwia szersze korzystanie z tych funkcji (szczegółowe informacje zawiera dokumentacja TWORZENIE FUNKCJI). Jeśli piszesz funkcję, powinieneś używać zmiennych tabel zamiast tabel tymczasowych, chyba że istnieje wyraźna potrzeba inaczej.
Zarówno zmienne tabel, jak i tabele tymczasowe są przechowywane w tempdb. Jednak zmienne tabel (od 2005 r.) Domyślnie zestawiają bieżącą bazę danych z tabelami temp, które przyjmują domyślne zestawienie tempdb ( ref ). Oznacza to, że powinieneś zdawać sobie sprawę z problemów z sortowaniem, jeśli używasz tabel tymczasowych, a sortowanie bazy danych różni się od tempdb, powodując problemy, jeśli chcesz porównać dane w tabeli tymczasowej z danymi w bazie danych.
Globalne tabele temperatur (## tmp) to inny rodzaj tabeli tymczasowej dostępnej dla wszystkich sesji i użytkowników.
Dalsza lektura:
Świetna odpowiedź Martina Smitha na dba.stackexchange.com
MSDN FAQ na temat różnic między nimi: https://support.microsoft.com/en-gb/kb/305977
Artykuł na blogu MDSN: https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-temporary-table
Artykuł: https://searchsqlserver.techtarget.com/tip/Temporary-tables-in-SQL-Server-vs-table-variables
Nieoczekiwane zachowania i wpływ na wydajność tabel tymczasowych i zmiennych tymczasowych: Paul White na SQLblog.com
źródło
Wystarczy spojrzeć na twierdzenie w zaakceptowanej odpowiedzi, że zmienne tabeli nie uczestniczą w logowaniu.
Wydaje się, ogólnie rzecz biorąc, nieprawdziwe, że istnieje jakakolwiek różnica w ilości rejestrowania (przynajmniej dla operacji
insert
/update
/delete
do samej tabeli, chociaż od tego czasu odkryłem, że istnieje niewielka różnica w tym zakresie dla buforowanych obiektów tymczasowych w procedurach przechowywanych z powodu dodatkowej tabeli systemowej aktualizacje).Patrzyłem na zachowanie rejestrowania zarówno dla tabeli
@table_variable
a, jak i#temp
dla następujących operacji.Rekordy dziennika transakcji były prawie identyczne dla wszystkich operacji.
Wersja zmiennej tabeli faktycznie ma kilka dodatkowych wpisów w dzienniku, ponieważ zostaje dodana do
sys.syssingleobjrefs
tabeli podstawowej (a później usunięta z niej), ale ogólnie zarejestrowano kilka mniej bajtów, ponieważ wewnętrzna nazwa zmiennych tabeli zużywa 236 bajtów mniej niż#temp
tabel (118 mniejnvarchar
znaków ).Pełny skrypt do odtworzenia (najlepiej uruchomić na instancji uruchomionej w trybie pojedynczego użytkownika i w
sqlcmd
trybie)Wyniki
źródło
INSERT ... SELECT
nie były minimalnie rejestrowane i nie możnaSELECT INTO ...
zmiennych tabeli.W przypadku mniejszych tabel (mniej niż 1000 wierszy) użyj zmiennej temp, w przeciwnym razie użyj tabeli temp.
źródło
@wcm - tak naprawdę, aby wybrać Tabela Zmienna nie jest tylko Ram - może być częściowo zapisana na dysku.
Tabela temp może mieć indeksy, podczas gdy zmienna tabeli może mieć tylko indeks podstawowy. Jeśli problemem jest prędkość Zmienne tabeli mogą być szybsze, ale oczywiście, jeśli istnieje wiele rekordów lub potrzeba przeszukiwania tabeli tymczasowej indeksu klastrowego, wtedy Tabela Temp byłaby lepsza.
Dobry artykuł w tle
źródło
Tabela temperatur: Tabela temperatur jest łatwa do tworzenia i tworzenia kopii zapasowych danych.
Zmienna tabeli: Ale zmienna tabeli wymaga wysiłku, gdy zwykle tworzymy normalne tabele.
Tabela temperatur: wynik tabeli temperatur może być używany przez wielu użytkowników.
Zmienna tabeli: Ale zmienna tabeli może być używana tylko przez bieżącego użytkownika.
Tabela temperatur: Tabela temperatur będzie przechowywana w tempdb. To spowoduje ruch w sieci. Gdy mamy duże dane w tabeli tymczasowej, musi ona działać w całej bazie danych. Wystąpi problem z wydajnością.
Zmienna tabeli: Ale zmienna tabeli będzie przechowywać w pamięci fizycznej niektóre dane, a następnie, gdy rozmiar wzrośnie, zostanie przeniesiona do tempdb.
Tabela temperatur: Tabela temperatur może wykonywać wszystkie operacje DDL. Pozwala tworzyć indeksy, upuszczać, zmieniać itp.,
Zmienna tabeli: Natomiast zmienna tabeli nie pozwala na wykonywanie operacji DDL. Ale zmienna tabelowa pozwala nam tworzyć tylko indeks klastrowany.
Tabela temperatur: Tabela temperatur może być używana dla bieżącej sesji lub globalnie. Aby sesja wielu użytkowników mogła wykorzystać wyniki z tabeli.
Zmienna tabeli: ale zmienna tabeli może być używana do tego programu. (Procedura składowana)
Tabela temp: Zmienna Temp nie może korzystać z transakcji. Kiedy wykonujemy operacje DML za pomocą tabeli tymczasowej, wówczas można ją wycofać lub zatwierdzić transakcje.
Zmienna tabeli: Ale nie możemy tego zrobić dla zmiennej tabeli.
Tabela temperatur: Funkcje nie mogą używać zmiennej temp. Co więcej, nie możemy wykonać operacji DML w funkcjach.
Zmienna tabeli: Ale funkcja pozwala nam użyć zmiennej tabeli. Ale używając zmiennej tabeli możemy to zrobić.
Tabela temp: procedura przechowywana dokona ponownej kompilacji (nie można użyć tego samego planu wykonania), gdy użyjemy zmiennej temp dla każdego kolejnego wywołania.
Zmienna tabeli: podczas gdy zmienna tabeli tak się nie robi.
źródło
Dla wszystkich, którzy wierzą w mit, że zmienne temp są tylko w pamięci
Po pierwsze, zmienna tabelowa niekoniecznie musi rezydować w pamięci. Pod presją pamięci strony należące do zmiennej tabeli można wypchnąć do tempdb.
Przeczytaj artykuł tutaj: TempDB :: Zmienna tabeli a lokalna tabela tymczasowa
źródło
Inną główną różnicą jest to, że zmienne tabelowe nie mają statystyk kolumnowych, podobnie jak tabele tymczasowe. Oznacza to, że optymalizator zapytań nie wie, ile wierszy znajduje się w zmiennej tabeli (zgaduje 1), co może prowadzić do wygenerowania wysoce nieoptymalnych planów, jeśli zmienna tabeli faktycznie ma dużą liczbę wierszy.
źródło
rows
Kolumnasys.partitions
jest utrzymywana dla zmiennych stołowych więc w rzeczywistości nie wiem, ile wierszy są w tabeli. Można to zobaczyć za pomocąOPTION (RECOMPILE)
. Ale brak statystyk kolumn oznacza, że nie można oszacować konkretnych predykatów kolumn.Cytat pochodzi z; Profesjonalne składniki wewnętrzne programu SQL Server 2012 i rozwiązywanie problemów
ZMIENNE TABELI NIE SĄ TWORZONE W PAMIĘCI
Istnieje powszechne błędne przekonanie, że zmienne tabel są strukturami w pamięci i jako takie będą działać szybciej niż tabele tymczasowe . Dzięki DMV o nazwie sys. dm _ db _ sesja _ przestrzeń _ użycie, które pokazuje użycie tempdb według sesji, możesz udowodnić, że tak nie jest . Po ponownym uruchomieniu programu SQL Server w celu wyczyszczenia DMV, uruchom następujący skrypt, aby potwierdzić, że twoja sesja _ id zwraca 0 dla użytkownika _ obiektów _ przydziel _ _ strona _ liczba:
Teraz możesz sprawdzić, ile miejsca zajmuje tymczasowa tabela, uruchamiając następujący skrypt, aby utworzyć tymczasową tabelę z jedną kolumną i wypełnić ją jednym wierszem:
Wyniki na moim serwerze wskazują, że do tabeli przypisano jedną stronę w tempdb. Teraz uruchom ten sam skrypt, ale tym razem użyj zmiennej tabeli:
Którego użyć?
źródło
Kolejna różnica:
Dostęp do tabeli var można uzyskać tylko z instrukcji w ramach procedury, która ją tworzy, a nie z innych procedur wywoływanych przez tę procedurę lub zagnieżdżonego dynamicznego SQL (przez exec lub sp_executesql).
Z drugiej strony zakres tabeli tymczasowej obejmuje kod w wywoływanych procedurach i zagnieżdżony dynamiczny SQL.
Jeśli tabela utworzona przez twoją procedurę musi być dostępna z innych wywoływanych procedur lub dynamicznego SQL, musisz użyć tabeli tymczasowej. Może to być bardzo przydatne w skomplikowanych sytuacjach.
źródło
Różnice między
Temporary Tables (##temp/#temp)
iTable Variables (@table)
są następujące:Table variable (@table)
jest tworzony wmemory
. Natomiast aTemporary table (##temp/#temp)
jest tworzony wtempdb database
. Jeśli jednak występuje presja pamięci, strony należące do zmiennej tabeli mogą zostać wypchnięte do tempdb.Table variables
nie może być zaangażowanytransactions, logging or locking
. To sprawia, że@table faster then #temp
. Tak więc zmienna tabeli jest szybsza niż tabela tymczasowa.Temporary table
pozwala na modyfikacje schematu w przeciwieństwie doTable variables
.Temporary tables
są widoczne w utworzonej procedurze, a także w procedurach potomnych. Natomiast zmienne tabeli są widoczne tylko w utworzonej procedurze.Temporary tables
są dozwoloneCREATE INDEXes
,Table variables
ale nie są dozwolone,CREATE INDEX
zamiast tego mogą mieć indeks za pomocąPrimary Key or Unique Constraint
.źródło
Weź również pod uwagę, że często możesz zastąpić obie tabelami pochodnymi, które również mogą być szybsze. Jednak, podobnie jak w przypadku dostrajania wydajności, tylko rzeczywiste testy na rzeczywistych danych mogą wskazać najlepsze podejście do konkretnego zapytania.
źródło
Zaskakuje mnie, że nikt nie wspomniał o kluczowej różnicy między tymi dwoma, że tabela temp obsługuje wstawianie równoległe, podczas gdy zmienna tabeli nie. Powinieneś być w stanie zobaczyć różnicę w stosunku do planu wykonania. A oto wideo z warsztatów SQL na kanale 9 .
To wyjaśnia również, dlaczego powinieneś używać zmiennej temp dla mniejszych tabel, w przeciwnym razie użyj tabeli temp, jak wcześniej odpowiedział SQLMenace .
źródło