2011-07-26 38 views
14

使用顯式創建表語句和加載數據與選擇到數據庫之間有任何性能差異。這個例子只顯示了2列,但問題是適用於使用非常大的表格。下面的例子也使用臨時表,但我想知道使用常規表的效果。儘管如此,我認爲它們會是相同的。使用顯式創建表語句創建表與選擇到

臨時表的場景:

--- 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 

或常規表:

--- 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 

什麼是大家對這個想法?我認爲明確創建表和加載必須比select into into更好的性能必須評估語句中的表達式才能創建表。

我們的組織通常會明確創建臨時表作爲標準做法,我們想知道什麼都認爲實際上是最佳實踐。

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

+0

我沒有時間檢查,但您可能會發現這是重新編譯的原因。這個潛在的開銷是否大於Adam Houldsworth所暗示的其他好處,我會留給你或其他人去找出:) – MatBailie

+0

你檢查過兩種變種的執行計劃嗎?你是否真的計時了他們,看看有沒有可衡量的差異? – HLGEM

+0

我已經嘗試了兩個更早,但不是在一大組數據。我現在沒有試圖解決任何性能問題,我很好奇每種插入方法的優缺點... – mservidio

回答

5

CREATE TABLE可以在插入數據之前更好地控制表格的定義,如NOT NULL,約束條件等等,您無法使用的東西SELECT INTO

SELECT INTO是一個最小化日誌操作,但在某些情況下,INSERT..SELECT也可以被最小化記錄。
The Data Loading Performance Guide,尤其是部分:總結最小測井條件

簡而言之,如果你不關心約束條件等(例如你想快速創建表的副本),那麼SELECT..INTO的好處就是代碼較短。
否則,您應該使用其他方式,並且您仍然可以將其記錄爲最低限度。

+0

感謝您的鏈接,看起來像一個偉大的文章。將來必須給它一個閱讀。 – mservidio

2

選擇到已登錄的好處(沒有做多),這樣的表現實際上是在大多數情況下更好。但是,如果表存在,它就會出錯,並且不會構建索引或約束等東西,只是列。

取決於你需要它。我知道我們有一些動作,SELECT ... INTO然後重命名,因爲它比更新舊錶更快(顯然有很多絨毛重建表對象等)。

請記住,我們的用法不適用於臨時表,我剛剛在您的問題中注意到這種情況。

對於具有索引的表,insert into必須將索引作爲插入過程的一部分進行維護。然後有其他表格對象可以導致更多的處理,例如觸發器。在select into的情況下,就我所知,表格是裸露的,因此初始插入表現非常好。加上事務日誌的影響是最小的(在你的問題中提到這個鏈接)。

這實際上取決於臨時表的使用情況,我認爲它們將會相對短暫,所以select into後跟截斷/ drop可以很好地工作。如果他們有更長的跨度,但以其他方式拋棄,再次選擇,然後最終下降可以工作。

如果他們需要在創建之後生存很長時間並且不會丟棄,那麼除了初始創建和插入數據(這將會很快)之外,您將隨後插入數據並返回原點 - 您最好只調整表格以接受快速插入,例如通過使用最小索引或先禁用索引並重新啓用插入後插入。

在大型表碰巧有聚簇索引的情況下,我也看到了一種技巧,插入數據時,聚集索引將插入數據。

+0

我會修改這個問題,我想知道不管表類型 – mservidio

+0

你知道如果'SELECT ... INTO#temp'會導致重新編譯嗎? – MatBailie

+0

@Dems不確定,對不起。 –

0

在我的情況下,執行顯式的CREATE,然後執行INSERT INTO在實際運行時間和優化器的估計成本方面明顯更好。

我的臨時表不是很大(8行),但其中一個值是計算的字符串值。在某些情況下,此臨時表與具有數十萬行的結果集結合在一起。我相信當我爲我的臨時表做一個SELECT INTO時,它並沒有爲計算出來的值選擇最佳的數據類型。所以,當我使用CREATE顯式定義列數據類型時,SQL Server能夠更高效地執行連接。當然,這個效應被誇大了,因爲涉及到很多行。

因此,在某些情況下,特別是當您的某個列是計算值時,CREATE和INSERT可能是更好的選擇。你的里程可能會有所不同,所以一定要進行一些測試!