Sql-Server

在 SQL Server 中插入一定數量的列後性能下降

  • November 26, 2016

我正在開發一個應用程序,它具有將表格數據導出到指定數據庫表的功能。該應用程序使用INSERT語句將其數據導出到目標數據庫。

插入是通過一個批處理INSERT語句完成的,每個 SQLINSERT語句有 100 行(現在我不能使用BULK INSERTor bcp)。

我注意到,當源數據中的列數超過某個數字時,導出時間會不成比例地增加(該數字不是固定的,取決於值的大小、每個值的行數INSERT等等)。

例如,導出 50 000 行(500 條INSERT語句,每條 100 行)隨機字元串,每行 100 個字元,每次 100 行INSERT

3 秒,5 列
6 秒,10 列
56 秒,15 列
77 秒,20 列

請注意 10 和 15 列之間的導出時間差異。我原以為 15 列的導出時間為 9-10 秒,但實際上要長 5 倍。在測試其他數據集的導出時,我能夠發現類似的性能下降。

為了確保問題不在我這邊,我INSERT通過sqlcmd.exe. 我得到了類似的結果。

**問題:**如何使 SQL Server 處理大量列的速度與處理小列一樣快?或者至少將性能下降點“移動”到更多列?

額外細節:

  • INSERT查詢在本地 SQL Server Express 2014(64 位)版本 12.0.5000.0 上執行;
  • 數據庫恢復模式設置為簡單;
  • 所有INSERT語句都包裝在一個事務中(我嘗試COMMIT在每個事務之後呼叫INSERT,但結果幾乎相同);
  • 目標表是在每次測試之前創建的。這是一個沒有任何索引、外鍵、約束等的簡單表;
  • 硬碟驅動器性能似乎不是問題的根源,因為在前兩個測試(5 列和 10 列)中,磁碟寫入速度是後兩個測試的sqlservr.exe10 倍。

表是這樣創建的:

CREATE TABLE [Test_Table]
(
   [Column 1] VARCHAR(255),
   [Column 2] VARCHAR(255),
   [Column 3] VARCHAR(255),
   [Column 4] VARCHAR(255),
   [Column 5] VARCHAR(255)
)

數據看起來像這樣(每個單元格實際上包含 100 個字元長的字元串,同一行中的所有字元串都相等):

+------------+------------+------------+------------+------------+
| [第 1 欄] | [第 2 欄] | [第 3 欄] | [第 4 欄] | [第 5 欄] |
+------------+------------+------------+------------+------------+
| R6YZ..uWaQ | R6YZ..uWaQ | R6YZ..uWaQ | R6YZ..uWaQ | R6YZ..uWaQ |
| DMNW..Kh0a | DMNW..Kh0a | DMNW..Kh0a | DMNW..Kh0a | DMNW..Kh0a |
| GKbg..yuap | GKbg..yuap | GKbg..yuap | GKbg..yuap | GKbg..yuap |
| pG+f..64bX | pG+f..64bX | pG+f..64bX | pG+f..64bX | pG+f..64bX |
| O2Q7..fTNF | O2Q7..fTNF | O2Q7..fTNF | O2Q7..fTNF | O2Q7..fTNF |

以下是重現該問題的兩個範例:

http://rextester.com/OZI56670(10列,~0.09 秒)

http://rextester.com/HLAP4972(11列,~0.45 秒)

您發布的 10 列和 100 行與 11 列和 100 行的複制之間的區別在於第一個的執行計劃使用Simple Parameterization

10 列的實際執行計劃列出了從@1到的參數@1000

11 * 1001100。但是一千似乎是自動參數化查詢可以達到的最大參數數量。

您正在為每個插入 10 次。在 10 列的情況下,計劃可以編譯一次,然後再用於其他 9 個插入。在 11 列的情況下,每個插入語句都需要單獨編譯。

此外,當 SQL Server 需要查看文字值時,編譯過程需要更長的時間,因為它會花時間計算組的屬性(或者至少以前是這種情況,我不確定這在最近的版本中是否發生了變化)。

引用自:https://dba.stackexchange.com/questions/155874