2011-07-26 13 views
14

Czy są jakieś różnice w wydajności między używaniem jawnie utworzyć instrukcję tabela i ładowanie danych a wybór w. Ten przykład pokazuje tylko 2 kolumny, ale pytanie jest ukierunkowane na używanie bardzo dużych tabel. W poniższym przykładzie wykorzystano również tabele tymczasowe, ale zastanawiam się również nad skutkami używania zwykłych tabel. Myślę, że byłyby takie same niezależnie od typu stołu.Tworzenie tabeli przy użyciu jawnie utworzyć instrukcję tabeli i wybrać w

Temp scenariusz tabela:

--- Explicitly creating temp table first and then loading. 
create table #test1 (id int, name varchar(100)) 
insert into #test1 (id, name) select id, name from #bigTable 

--- Creating temp table by selecting into. 
select id,name into #test2 from #bigTable 

lub regularne stoły:

--- Explicitly creating table first and then loading. 
create table test1 (id int, name varchar(100)) 
insert into test1 (id, name) select id, name from #bigTable 

--- Creating table by selecting into. 
select id,name into test2 from bigTable 

Jakie są każdego z nas myśli o tym? Myślę, że jawne tworzenie tabeli i ładowanie musi mieć lepszą wydajność, niż wybór w selekcji w musi ocenić wyrażenia w instrukcji w celu utworzenia tabeli.

Nasza organizacja zazwyczaj tworzy tabele tymczasowe jako standardową praktykę i zastanawiamy się, co według mnie jest najlepszą praktyką.

http://msdn.microsoft.com/en-us/library/ms188029.aspx

+0

Nie mam czasu na sprawdzenie, ale może się okazać, że jest to przyczyną ponownej kompilacji. Niezależnie od tego, czy ten potencjalny narzut jest większy niż inne korzyści sugerowane przez Adama Houldswortha, zostawię to Tobie lub innym, aby się przekonać :) – MatBailie

+0

Czy sprawdziłeś plany wykonania obu wariantów? Czy właściwie je ustaliłeś, by sprawdzić, czy istnieje mierzalna różnica? – HLGEM

+0

Próbowałem już wcześniej, ale nie na dużym zestawie danych. Nie próbuję rozwiązać problemu z wydajnością w tej chwili, jestem ciekawy co do zalet/wad każdej metody robienia wstawki ... – mservidio

Odpowiedz

5

CREATE TABLE daje lepszą kontrolę nad definicją tabeli przed wstawieniem danych, takich jak NOT NULL, wiązań itp. Rzeczy, których nie można wykonać przy użyciu SELECT INTO.

SELECT INTO to operacja o minimalnym logowaniu, ale w pewnych warunkach można również minimalnie zalogować się pod numerem INSERT..SELECT.
Zobacz The Data Loading Performance Guide, szczególnie w sekcji: Podsumowując minimalne warunki rejestrowania.

Krótko mówiąc, jeśli nie zależy Ci na ograniczeniach itd. (Np. Chcesz szybko utworzyć kopię tabeli), zaletą jest to, że IMHO jest krótszym kodem.
W przeciwnym razie powinieneś skorzystać z drugiej strony, a nadal będziesz mieć możliwość minimalnego zalogowania.

+0

Dzięki za link, wygląda jak świetny artykuł. Będzie musiał to przeczytać później. – mservidio

2

Wybierz się działo zalogowaniu korzyści (nie robić tak dużo), więc wydajność jest lepsza w większości przypadków. Jednak błędy, jeśli tabela istnieje i nie buduje rzeczy takie jak indeksy lub ograniczenia, tylko kolumny.

Zależy od tego, czego potrzebujesz. Wiem, że mamy pewne działania, które zmienią nazwę na SELECT ... INTO, ponieważ jest to szybsze niż aktualizowanie starej tabeli (oczywiście z dużą ilością fluff dookoła, aby odbudować obiekty tabeli itp.).

Pamiętaj, że nasze użycie nie dotyczy tabel tymczasowych, co właśnie zauważyłem w Twoim pytaniu.

W przypadku tabel z indeksami, wstaw do będzie musiał zachować indeksy jako część procesu wstawiania. Istnieją wtedy inne obiekty tabel, które mogą powodować więcej przetwarzania, takie jak wyzwalacze. W przypadku wyboru na, tabela jest bare-kości, o ile wiem, więc początkowa wydajność wstawiania jest świetny. Dodatkowo wpływ dziennika transakcji jest minimalny (wspomina to w tym łączu na twoim pytaniu).

To naprawdę zależy od użycia, w przypadku tabel tymczasowych, przypuszczam, że będą one stosunkowo krótkotrwałe, więc wybór w następujący po nich ścięty/upuszczony może działać dobrze. Jeśli mają dłuższe przęsła, ale w przeciwnym razie zostaną odrzucone, można ponownie wybrać i obserwować ewentualny zrzut.

Jeśli muszą żyć długo po stworzeniu i nie są wyrzucane, wtedy inne niż początkowe utworzenie i wstawienie danych (które będą szybkie), powrócisz i wyzerujesz je pod kątem kolejnych wstawek - najlepiej byłoby po prostu dostroić tabelę, aby zaakceptować szybkie wstawki, na przykład przez posiadanie minimalnych indeksów lub wyłączenie indeksów przed ponownym włączeniem wstawiania wpisu.

W przypadku dużych tabel, które mają indeksy klastrowe, widziałem również sztuczkę, w której wstawiane dane są uporządkowane według indeksu klastrowego we wkładce.

+0

Zmodyfikuję pytanie, zastanawiam się, wydajność, niezależnie od typ tabeli – mservidio

+0

Czy wiesz, że "WYBIERZ ... W TYM TEMP" spowoduje ponowną kompilację? – MatBailie

+0

@Dems nie pewny, przepraszam. –

0

W moim przypadku wykonanie jawnego CREATE, a następnie INSERT INTO wykonało zauważalnie lepszą zarówno w rzeczywistym czasie pracy, jak i szacunkowym koszcie przez optymalizator.

Moja tabela temp nie była duża (8 wierszy), ale jedną z wartości była obliczona wartość ciągu. W niektórych przypadkach do tej tabeli tymczasowej dołączono zestaw wyników zawierający setki tysięcy wierszy. Uważam, że kiedy zrobiłem SELECT INTO dla mojej tabeli temp, to nie optymalnie wybrałem typ danych dla obliczonej wartości. Tak więc, gdy jawnie zdefiniowałem typy danych kolumn przy użyciu CREATE, SQL Server był w stanie wykonać połączenie bardziej efektywnie. Efekt ten był oczywiście przesadzony, ponieważ dotyczyło to wielu rzędów.

Wydaje się, że w niektórych przypadkach, szczególnie gdy jedna z kolumn jest wartością obliczoną, lepszym rozwiązaniem może być tworzenie i wstawianie. Twój przebieg może się różnić, więc koniecznie przeprowadź kilka testów!

Powiązane problemy