2009-10-23 130 views
7

這對於數以百萬計的記錄速度是:永久表臨時表?表VS臨時表的性能

我只能使用它爲1500萬條記錄。處理完成後,我們刪除這些記錄。

+2

這很大程度上取決於情況。你想用它做什麼? – 2009-10-23 18:49:21

+0

Permannent表。您連接到服務器,百萬條記錄已經存在,無需任何操作,亞納秒時間! ......也許你很想詳細說明你的問題? – 2009-10-23 18:53:53

+0

我必須處理5000萬條記錄。爲此我必須創建永久/臨時表。 情景是:對於處理5000萬條記錄,我創建了另一個?/?表並插入到此表中。然後我應用優先級爲(Fname)並將其插入到另一個永久\臨時表中並從第一個表中刪除。並應用優先級2,然後再重新執行第一步。所以我問了這個問題。請回復。 – ManishKumar1980 2009-10-23 19:04:22

回答

14

在你的情況,我們使用一個永久表稱爲臨時表。這是大量進口的常用方法。實際上,我們通常使用兩個臨時表,一個包含原始數據,另一個包含清理後的數據,這使得用Feed更容易研究問題(它們幾乎總是由我們的客戶發送給我們的新的多種方式產生的,我們必須能夠證明這一點)。另外,您避免像有成長臨時數據庫或導致問題誰想要使用的臨時數據庫,但必須等待它成長爲你的其他用戶等問題

您還可以使用SSIS並跳過臨時表(S ),但我發現無需重新加載50,000,000張桌子就可以返回並進行研究,這非常有幫助。

+0

SSIS可能是最好的解決方案 – 2009-10-23 19:39:01

+2

+1指出了額外的好處在發生錯誤時可以看到分階段的數據 - 「您也可以使用SSIS並跳過登臺表,但我覺得無需重新加載50,000,000個表格就可以返回並進行研究,這非常有幫助。」 – Mayo 2009-10-23 19:40:43

2

永久表是更快,如果表結構是100%相同的,因爲沒有開銷分配空間和建表。

臨時表是在某些情況下更快(例如,當你不需要的索引是存在於永久表,這將減緩插入/更新)

-1

臨時表是在內存中(除非他們太大),所以理論上它們應該非常快。 但通常不會。 作爲一個經驗法則,儘量遠離臨時表,除非這是唯一的解決方案。 你能給我們提供一些關於你想要做什麼的更多信息嗎?這也許可以用一個派生查詢

+7

Temp變量存儲在Memory not Temp表中。 – ManishKumar1980 2009-10-23 18:57:00

+1

我沒有看到問題是MSSQL。在MySQL中,您可以聲明一個臨時內存表:'CREATE TEMPORARY TABLE test ENGINE = MEMORY' – adamJLev 2009-10-23 21:53:53

+1

表變量顯然也存儲在tempdb中 - 請參閱http://dba.stackexchange.com/questions/16385/whats-the-difference- 16386#16386 – flash 2014-03-14 15:36:40

0

我個人會使用一個永久性表並在每次使用前截斷它。根據我的經驗,它更容易理解/維護。然而,我最好的建議是嘗試兩種方法,看看哪一種效果更好。

+2

只有當這個進程是一個singleton,並且沒有任何其他進程在此期間啓動並且還需要使用該表的情況下,這纔會起作用。 我們有導入大量數據的進程,因爲多個進程可能同時運行,所以我們無法截斷單個表。 – 2009-10-24 14:26:53

+0

您可以通過使用具有唯一列的perm表來標識導入過程,該過程使用特定的一組數據。我們有這些用於用戶驅動的基於文件的導入(而不是截斷工作正常的夜間批處理)。可能考慮一個清理過程來檢查桌子的大小。 – Mayo 2009-10-25 13:05:52

11

如果不使用tempdb,請確保您的工作在數據庫的恢復模式未設置爲「全」。這會在這些50M行插入上造成很多開銷。

理想情況下,你應該使用一個臨時數據庫,簡單恢復模式,在RAID 10,如果可能的話,並調整其大小提前爲所有您的操作提供足夠的空間。關閉自動增長。

使用INSERT ... WITH(TABLOCK),以避免行級日誌記錄:

INSERT INTO StagingTable WITH (TABLOCK) (.....) 
SELECT ..... 

同樣的BULK INSERT。如果刪除並重新創建,請先創建您的聚簇索引,然後再插入。如果不能,首先插入一個表中,然後將其插入到具有正確羣集的另一個表中,然後截斷第一個表。如果可能的話,避免在BULK INSERT上使用小批量。請仔細閱讀BULK INSERT文檔,因爲您可以通過錯誤的選項來破壞性能。

避免INSERT ... EXEC。每一行都被記錄下來。

避免更新,除非你需要計算運行總和。通常,從一個表插入另一個表比較便宜,然後截斷第一個表,而不是更新到位。運行總計算是例外,因爲它們可以通過UPDATE和變量在行之間累積值來完成。

避免表控制結構以外的表變量,因爲它們阻止並行化。不要將您的50M行表連接到表變量,而是使用臨時表。

不要害怕迭代的遊標。使用遊標變量,並使用STATIC關鍵字針對聚集索引前面的低基數列聲明它們。用這個將大表分成更易於管理的塊。

不要試圖在任何一個陳述中做太多。

+0

非常不錯和Satisfoctory答案。感謝所有人 – ManishKumar1980 2009-10-24 07:40:57