2010-09-09 32 views
2

步驟1:通過從.txt「大容量插入」(分隔)文件導入表1中加載的數據(沒有索引等)什麼是從巨大表中刪除「非唯一」值的「最佳實踐」?

bulk insert Table_1 
from '\\path\to_some_file.txt' 
with (tablock, FORMATFILE ='format_file_path.xml') 

通過格式文件I映射輸出列數據類型以避免進一步的轉換(從CHAR到INT例如)

步驟2:將結果輸出(也許不是所有來自表1)列到另一表2中,但只有不同的值從表1中。

NB! Table_1約爲2000萬條記錄(每個負載)。

我們現在有(例如簡化):

select distinct convert(int, col1), convert(int, col2), col3, ... 
into Table_2 
from Table_1 

大約需要3.5分鐘來處理。 您能否建議一些可能有助於減少處理時間並將唯一記錄放入Table_2的最佳做法?

在此先感謝!

UPD 1:誤解對不起 - 我的意思是選擇不同的查詢需要3.5分鐘。 「批量插入」相當優化 - 它通過8個線程(8個單獨的.txt文件)「批量插入」加載到1個帶有(TABLOCK)的表中,並在大約1分鐘內導入20毫升記錄。

UPD 2:我測試了不同的方法(在SSIS沒有測試 - 在我們的應用這種方法是行不通的): 最好的結果是,當數據「批量插入」到TABLE_2格式已經接近(列類型匹配,數據類型 - 也),所以我們消除數據類型轉換。並且只是「明顯」不同:

select distinct * into Table_2 from Table_1 

進行70秒的處理。所以我可以考慮這是我現在可以得到的最好結果。 我也嘗試了一些技巧(額外的命令,CTE贏分組等) - 他們更糟糕,然後「明顯」不同。

謝謝大家的參與!

+0

3.5分鐘聽起來很合理。你爲什麼需要它更快?這是你經常做的事嗎?你爲什麼經常這樣做?你有沒有考慮其他方法來解決這個問題? – 2010-09-09 16:05:06

+0

嗯..我只是試圖澄清自己,如果沒關係。因爲我們應用程序中的很多部分不是非常優化。是的,我們每週都會處理這麼多的數據。因爲我們有很多來自客戶的數據(並且有很多數據)。如果我們每月都這樣做一次 - 在我的示例中處理所有數據(有很多處理步驟)需要一天的時間 - 這只是流程的一小部分。 – zmische 2010-09-09 17:24:17

+3

也許你的CONVERT語句正在放慢速度。 – Sam 2010-09-09 17:49:38

回答

2

您必須知道是否您的SELECT DISTINCT導致問題或您的INSERT INTO導致問題。

您將不得不一次運行SELECT DISTINCT,並且一次沒有INSERT INTO,並測量持續時間以確定您需要調整哪一個。

如果是您的SELECT DISTINCT,您可以嘗試微調該查詢以提高效率。

如果這是你的INSERT INTO,然後考慮以下幾點:

隨着INSERT INTO,創建一個新表,並根據需要將所有頁面分配。

您是否丟棄舊錶並創建新表?如果是這樣,您應該將其更改爲僅從舊錶中刪除 - DELETE,而不是截斷 - 這是因爲截斷將放棄由表獲取的所有頁面,並且它們必須重新分配。

您可以嘗試以下一種或幾種方法來提高效率。

  1. 問你的客戶的非重複數據 上的所有重複,標準列
    • 指數。掃描索引應比掃描錶快得多。
    • 劃分您的臨時表以獲得更好的性能
    • 創建一個視圖,選擇不同的值並使用BCP快速加載數據。
+0

+1 - 詢問哪兩個是問題。 – 2010-09-09 16:22:20

+0

我嘗試瞭解 - 也許有一種方法可以在步驟1階段「刪除」重複項(同時批量插入???)我們擁有帶暫存表的DataMart - 它們每週/每天/每月使用數據加載數據我們需要導入並處理和消除重複數據,並且我們有來自Customer的.txt(bcp-outed)數據 – zmische 2010-09-09 17:17:58

+0

@zmische您的數據以.txt文件形式存在,然後刪除文件中的重複項將會非常困難從一個數百萬行集重複刪除是一個基於集合的操作,最適合於一個好的RDBMS。 – 2010-09-09 23:44:59

1

找到那些重複的然後刪除,然後複製到table2。

查找重複這樣

SELECT col1, 
COUNT(col1) AS NumOccurrences 
FROM table1 
GROUP BY col1 
HAVING (COUNT(col1) > 1) 
+0

我想zmische希望保留其中一個副本 - 似乎這很難用你的方法。 – Aivar 2010-09-09 16:07:40

+0

的確,我需要從2+記錄中選擇一個。 – zmische 2010-09-09 17:16:03

+0

+1用戶名 – 2010-09-09 17:22:50

-3

我建議建立一個遊標,通過所有領域下令所有行去,並使用變量來比較當前行與前一行來檢測,如果該行已被看到。你可以在這個過程中刪除重複的行,或者創建一個只包含唯一行的關係(對不起,不知道SQL服務器的確切術語)的過程(如果你檢測到重複,那麼你跳過這一行,即不要屈服)。

+1

-1用於建議光標。基於集合的操作是RDBMS的強點之一。遊標是可以避免的,必須避免。 – 2010-09-09 16:09:27

+0

嗯,遊標有什麼問題? – Aivar 2010-09-09 16:12:02

+0

true,聲明風格的數據選擇更好,但是這個人關注效率 – Aivar 2010-09-09 16:13:52

0

這就是SSIS所關心的,男人。 :)

[更新]

試試這個SSIS中看到的速度有多快,你可以通過這些數據咀嚼:

平面文件源 - >與刪除重複排序組件 - >平面文件目的地(或帶有tablock和東西的Ole Db目的地)

+0

SSIS基於本機t-SQL查詢,所以我只是試着去做「低」的水平,SSIS只是一個用於可視化的IDE,它是好的,但問題仍然存在!)))如果你證明了,SSIS會更快 - 我會很樂意使用你的方法 – zmische 2010-09-09 17:33:47

+0

@zmische好吧, sql方法的問題是在大量數據的情況下,它會生成一個同樣巨大的事務日誌,並且會降低速度。另一方面,SSIS可能零零碎碎地操作,並且您可以控制並行流程,並且專門設計用於接受不同格式的文件。 – 2010-09-09 18:05:33

+0

@zmische刪除重複項的另一種方法是創建一個沒有聚集索引和唯一索引的登臺表,並在表上有選項'IGNORE_DUP_KEY = ON'。 – 2010-09-09 18:09:04

0

您的CONVERT語句可能會導致延遲。