1. 程式人生 > >大資料匯入之Bulk Insert的一點總結

大資料匯入之Bulk Insert的一點總結

最近專案中需要對服務程式進行大規模的模擬測試,於是專門寫了一個測試程式,測試程式包含:測試資料的管理,功能測試,流程測試,壓力測試。

    對於要測試的程式的資料來源來自資料庫,所以,需要模擬一個大的資料量,從1W,10W,100W,1000W...。其實,一直以來沒有怎麼搞過大資料,寫程式的時候,最多搞一兩條記錄測試一下功能,功能OK了就提交程式碼,進行下一步測試了。但是,進行實際的測試中,總是有這樣或者那樣的問題冒出來,歸根到底是測試做的不夠,特別是服務程式,穩定性的保障是排在第一位的,所以,一個服務程式進行大規模的資料測試是很有必要的。也是因為沒有怎麼處理過大資料,所以,當我嘗試插入100W資料的時候,我使用的方式竟然是Append+Post,效率的低下可想而知,這種低效率的痛苦也迫使我設法換一個方案,或者增加一個介面,以便能夠快速的完成模擬資料的插入。

    其實之前搞過BCP,網上查了下,也有一種Bulk Insert的方式可以使用。

    那先說一下BCP這種方式:BCP這種方式,其實是呼叫個SQL Server提供的一個工具,使用者採用命令列的方式呼叫,是將一個格式化的字串文字匯入到資料庫,效率比較高,而且,BCP的執行不一定要在SQL Server那一側,執行環境沒有裝SQL Server也可以,只要將BCP相關的檔案拷貝到執行目錄就行,這個是相對於Bulk Insert相對比較方便的地方,但是,就我使用的經歷來看,BCP也有一個風險:採用呼叫BCP程序的方式,有時候會出現啟動程序失敗的問題。

   說說Bulk Insert。從查詢資料到搞定用了4個小時,其實整個過程還是比較順利的,說一說它的特點:

   1 Bulk Insert是SQL Server提供的一個命令,可以使用SQL語句的方式使用。

    2 也是將預定格式的文字批量匯入到資料庫中,如果資料檔案不在SQL Server那一側,需要使用UNC的檔案路徑,這個比較不爽,這個有時候會涉及到許可權的問題,所以,暫時沒有使用,但是,這個往往出現一個錯誤,說是找不到指定的檔案,其實就是遠端執行這個命令,而且資料檔案也不在伺服器上就會出現提示打不開指定檔案的錯誤資訊。

    3 可以使用with ()進行一些約束,一般欄位之間使用一個字元隔開,就需要使用約束說明欄位的分割符號,否則,也會報錯。

    4 某個欄位為NULL,並且無值或者自增主鍵,那麼就保持空白,新增一個欄位分隔符就行,在匯入的時候就會正確的解析匯入。

    5 如果最後一個欄位有值,就不需要再輸入欄位分割符號了,如果表示為NULL,則需要增加一個欄位分割符號。

    6 使用回車換行符號隔開兩行記錄,就不需要在約束中指明行隔開符號。

    7  這種方式匯入是事務安全的

    8 由於使用SQL語句的方式匯入,需要需要考量資料量大小,從而靈活的設定命令執行的超時時長。

    9  每個記錄文字需要保證新增一個空行

    上面9條就是Bulk Insert的初次使用的一個感受,通過SQL語句比使用BCP簡潔,執行的效率確實快,我在一個8核的機器上,匯入1000W記錄,用了4分鐘左右。

    BCP/Bulk Insert都是基於格式化文字,如果資料量小,不過於追求效率,append,post這些已經夠用了,BCP/Bulk Insert折騰起來有時候也會遇到很多問題,只是一旦搞定了,用著也很安心。對比兩者,我還是傾向於Bulk Insert的方式,在一個Connection中完成,不必輸入太多的資訊,更加關注與資料。

    感受:解決問題的方案有好多種,這些方法都有個各自的特點,具體使用哪種方法需要考察使用的場景,不能一條路走到死,否則,就死路一條了。1000W/4Min,這個效率在某些真正的大資料量的情況可能還是不夠,那也許就要用到其他的方式。