2013-07-24 22 views
2

在我的存儲過程中,我使用SELECT INTO語法將數據插入到本地臨時表(即#LocalTable)。我目前不寫這個表的CREATE TABLE命令。我是否必須顯式創建#temp表?

是否首選明確編寫CREATE TABLE命令並定義列架構?沒有定義模式,使用方便的SELECT INTO表有沒有缺點?

回答

4

SELECT INTO的一些缺點:

  1. ,你可能會得到的數據類型/長度/精度/規模驚喜。

  2. 您可能會從源表中保留IDENTITY屬性,但並非總是(取決於源查詢是否引用多個表)。

  3. 如果沒有明確的創建,select into的存在可能難以找到代碼的其他維護者,並且它還會強制他們對代碼進行反向工程以試圖找出臨時表的模式。

一些優點:

  1. 你去偷懶一次。

  2. 有些情況下,它可能會稍微好一些,但如果您稍後要添加索引等,這種差異將可以忽略不計(並且不會證明我對此說過的所有內容)。

+0

我不明白第二點,對不起。你可以擴大或改寫一下嗎?感謝您的幫助。如果你有一個你信任的文章的鏈接,那麼我會做作業並閱讀它。 – MADCookie

+1

@MADCookie好吧,如果你有一個帶有'IDENTITY'列的表,並且你做了'SELECT x.ID INTO #foo FROM x INNER JOIN y ON x.ID = y.ID;',新的列表格不會是'IDENTITY'列。如果將查詢更改爲返回完全相同結果但在from子句中只有一個表的內容,例如'SELECT x.ID INTO #foo FROM x WHERE EXISTS(SELECT 1 FROM y WHERE y.ID = x.ID);'那個臨時表將有一個'IDENTITY'列。我說這是一個缺點,因爲它不直觀,如果你想明確地控制它,你應該使用'CREATE TABLE'。 –

+0

@MadCookie我假設你的意思是#2,因爲它們有兩個。 –

0

我不認爲有性能差異,但我用CREATE TABLE和定義列架構時,我必須爲臨時表創建索引。有了大量的數據,這項技術可以顯着提高速度。

例如:

CREATE TABLE #tmpTable(ID int not null) 
CREATE CLUSTERED INDEX Id_CI ON #tmpTable(ID ASC); 

INSERT INTO #tmpTable 
SELECT [....] 

用它使代碼更易讀,但更剛性的(這是我的意見)之前創建表。

的另一種方法是使用:

WITH tmpTable AS (
     SELECT [...] 
    ) 

    [Command on tmpTable] 
END 

我不夠成SQL性能分析知道的解決方案是更快或者一個使用更少的資源。

希望它有幫助。

+2

請注意,CTE與#temp表不一樣,所以嚴格來說這不是一個直接的選擇。一個常見的誤解是CTE只進行一次評估,但只有當查詢的其餘部分僅引用一次時纔是如此。它的行爲更像一個視圖,而不是#temp表。 –

+0

我指的是CTE作爲替代方法,因爲你有一個對象在某種程度上可以與臨時表相媲美,在存儲過程執行期間處於活動狀態並在其執行後銷燬。我對嗎?感謝@ Aaron-Bertrand的更正。 –

+0

不,在您銷燬它之前(或直到您超出範圍),#temp表將處於活動狀態。 CTE僅適用於創建它的語句。 –

相關問題