Uczę się więcej szczegółów w zmiennej tabeli. Mówi, że tabele temp są zawsze na dysku, a zmienne tabeli są w pamięci, co oznacza, że wydajność tabeli jest lepsza niż tabela temp, ponieważ zmienna tabeli używa mniej operacji IO niż tabela temp.
Ale czasami, jeśli w zmiennej tabeli jest zbyt wiele rekordów, których nie można zapisać w pamięci, zmienna tabeli zostanie umieszczona na dysku jak tabela tymczasowa.
Ale nie wiem, co to jest „zbyt wiele płyt”. 100 000 rekordów? lub 1000 000 rekordów? Skąd mam wiedzieć, czy zmienna tabeli, której używam, znajduje się w pamięci lub na dysku? Czy w SQL Server 2005 jest jakaś funkcja lub narzędzie do mierzenia skali zmiennej tabeli lub powiadamianie mnie, kiedy zmienna tabeli jest umieszczana na dysku z pamięci?
tempDB
- że „w pamięci” to mit. Ponadto: zmienne tabeli zawsze będą traktować optymalizator zapytań, aby zawierał dokładnie jeden wiersz - jeśli masz dużo więcej, może to prowadzić do poważnie złych planów wykonania.tempdb
pamięci (ale może też być całkowicie w pamięci)Odpowiedzi:
Twoje pytanie pokazuje, że uległeś częstym nieporozumieniom dotyczącym zmiennych tabel i tabel tymczasowych.
Na stronie DBA napisałem dość obszerną odpowiedź temat różnic między tymi dwoma typami obiektów. To także dotyczy twojego pytania o dysk vs pamięć (nie widziałem żadnej znaczącej różnicy w zachowaniu między nimi).
Jeśli jednak chodzi o pytanie zawarte w tytule, kiedy użyć zmiennej tabeli zamiast lokalnej tabeli tymczasowej, nie zawsze masz wybór. Na przykład w funkcjach możliwe jest tylko użycie zmiennej tabeli, a jeśli musisz zapisać do tabeli w zakresie potomnym,
#temp
zrobi to tylko tabela (parametry wyceniane w tabeli umożliwiają dostęp tylko do odczytu ).Tam, gdzie masz wybór, poniżej znajdują się niektóre sugestie (chociaż najbardziej niezawodną metodą jest po prostu przetestowanie obu z określonym obciążeniem).
Jeśli potrzebujesz indeksu, którego nie można utworzyć na zmiennej tabeli, to oczywiście potrzebujesz
#temporary
tabeli. Szczegóły tego są jednak zależne od wersji. W przypadku SQL Server 2012 i niższych jedynymi indeksami, które można utworzyć na zmiennych tabeli, były te niejawnie utworzone za pomocą ograniczeniaUNIQUE
lubPRIMARY KEY
. SQL Server 2014 wprowadził wbudowaną składnię indeksu dla podzbioru opcji dostępnych wCREATE INDEX
. Zostało to przedłużone, aby umożliwić filtrowane warunki indeksu. Indeksy zINCLUDE
kolumnami -d lub indeksami magazynu kolumn nadal nie są jednak możliwe do utworzenia w zmiennych tabeli.Jeśli będziesz wielokrotnie dodawać i usuwać dużą liczbę wierszy z tabeli, użyj
#temporary
tabeli. To obsługujeTRUNCATE
(co jest bardziej wydajne niż wDELETE
przypadku dużych tabel) i dodatkowo kolejne wstawki poTRUNCATE
mogą mieć lepszą wydajność niż te po a,DELETE
jak pokazano tutaj .#temporary
tabeli. Wspiera to tworzenie statystyk, które pozwalają na dynamiczną rekompilację planu zgodnie z danymi (chociaż w buforowanych tabelach tymczasowych w procedurach przechowywanych zachowanie rekompilacji należy rozumieć osobno).SELECT
instrukcja, należy wziąć pod uwagę, że użycie zmiennej tabeli zablokuje taką możliwość przy użyciu planu równoległego.#temp
tabeli w obrębie użytkownika blokady transakcji mogą być przechowywane dłużej niż w przypadku zmiennych tabeli (potencjalnie do końca transakcji w porównaniu z końcem instrukcji w zależności od rodzaju blokady i poziomu izolacji), a także mogą zapobiec obcięciutempdb
dziennika transakcji do czasu transakcja użytkownika kończy się. Może to sprzyjać stosowaniu zmiennych tabeli.#temporary
tabel. Bob Ward podkreśla w swojejtempdb
prezentacji, że może to powodować dodatkowe spory o tabele systemowe w warunkach wysokiej współbieżności. Ponadto w przypadku niewielkich ilości danych może to mieć wymierną różnicę w wydajności .Efekty udostępniania zestawu wierszy
źródło
id
i używaniemOPTION (RECOMPILE)
prawdopodobnie byłaby do tego odpowiednia - ale przetestuj oba.Użyj zmiennej tabeli, jeśli dla bardzo małej ilości danych (tysiące bajtów)
Użyj tabeli tymczasowej dla dużej ilości danych
Inny sposób myślenia o tym: jeśli uważasz, że możesz skorzystać z indeksu, automatycznych statystyk lub dowolnego dobrodziejstwa optymalizatora SQL, oznacza to, że Twój zestaw danych jest prawdopodobnie zbyt duży dla zmiennej tabeli.
W moim przykładzie chciałem po prostu wstawić około 20 wierszy do formatu i zmodyfikować je jako grupę, zanim użyję ich do UPDATE / INSERT stałej tabeli. Zatem zmienna stołowa jest idealna.
Ale uruchamiam też SQL, aby zapełniać tysiące wierszy jednocześnie i zdecydowanie mogę powiedzieć, że tabele tymczasowe działają bardzo dobrze lepiej niż zmienne tabel.
Nie inaczej jest w przypadku, gdy CTE są przedmiotem zainteresowania z podobnej wielkości - jeśli dane w CTE są bardzo małe, uważam, że CTE działa tak dobrze lub lepiej niż to, co oferuje optymalizator, ale jeśli jest dość duży, to bardzo cię boli.
Moje rozumienie opiera się głównie na http://www.developerfusion.com/article/84397/table-variables-v-temporary-tables-in-sql-server/ , który zawiera znacznie więcej szczegółów.
źródło
Microsoft mówi tutaj
źródło
Całkowicie zgadzam się z Abacusem (przepraszam - nie mam wystarczającej liczby punktów do skomentowania).
Pamiętaj również, że niekoniecznie sprowadza się to do liczby posiadanych rekordów, ale do ich rozmiaru .
Na przykład, czy wziąłeś pod uwagę różnicę wydajności między 1000 rekordów z 50 kolumnami w porównaniu do 100 000 rekordów z tylko 5 kolumnami w każdym?
Wreszcie, może przeszukujesz / przechowujesz więcej danych niż potrzebujesz? Oto dobry tekst na temat strategii optymalizacji SQL . Ogranicz ilość pobieranych danych, szczególnie jeśli nie używasz ich wszystkich (niektórzy programiści SQL są leniwi i po prostu wybierają wszystko, mimo że używają tylko niewielkiego podzbioru). Nie zapomnij, że analizator zapytań SQL może stać się twoim najlepszym przyjacielem.
źródło
Tabela zmiennych jest dostępna tylko dla bieżącej sesji, na przykład, jeśli potrzebujesz
EXEC
innej procedury składowanej w ramach bieżącej, musisz przekazać tabelę, ponieważTable Valued Parameter
i oczywiście wpłynie to na wydajność, z tabelami tymczasowymi możesz to zrobić tylko przekazanie nazwy tabeli tymczasowejAby przetestować tabelę tymczasową:
Aby przetestować tabelę zmiennych:
coś innego, czego doświadczyłem to: Jeśli twój schemat nie ma
GRANT
uprawnień do tworzenia tabel, użyj tabel zmiennych.źródło
zapisując dane w zadeklarowanych tabelach
declare @tb
i po połączeniu z innymi tabelami, zdałem sobie sprawę, że czas odpowiedzi w porównaniu do tabel tymczasowychtempdb .. # tb
jest znacznie dłuższy.Kiedy dołączam do nich @tb, czas na zwrócenie wyniku jest znacznie dłuższy, w przeciwieństwie do #tm , zwrot jest niemal natychmiastowy.
Wykonałem testy z łączeniem 10.000 wierszy i łączeniem z 5 innymi tabelami
źródło