Sql-Server

遠端執行多插入批處理比本地慢 5 倍

  • December 4, 2020

我使用每行的 INSERT .. VALUES 語句將 30.000 行插入到一個表中。

查看測試環境:

表創建:

CREATE TABLE [dbo].[TestInsert](
   [Col1] [int] NOT NULL,
   [Col2] [varchar](16) NOT NULL,
   [Col3] [varchar](15) NOT NULL,
   [Col4] [int] NULL,
   [Col5] [datetime] NOT NULL,
   [Col6] [nvarchar](128) NOT NULL
)

批量插入行:

INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491073,N'D0058A79AE',N'OCIP',51849,'20100823 10:02:04.683',N'TUVWXYZabcdefgh')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491074,N'D00559B4C4',N'OCIP',62488,'20100823 10:02:04.710',N'CDEFGHIJKLMNOPQ')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491075,N'D005AB75B6',N'OCIP',52836,'20100823 10:05:17.070',N'BCDEFGHIJKLMNOP')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491076,N'D0070B9F25',N'OCIP',62554,'20100825 08:03:08.260',N'BCDEFGHIJKLMNOP')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491077,N'D00753F2D7',N'OCIP',62554,'20100825 08:03:58.733',N'UVWXYZabcdefghi')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491078,N'D0070B979A',N'OCIP',62554,'20100825 08:04:09.917',N'STUVWXYZabcdefg')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491079,N'D0070B6F37',N'OCIP',62554,'20100825 08:04:21.043',N'CDEFGHIJKLMNOPQ')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491080,N'D0070B86F3',N'OCIP',62554,'20100825 08:05:28.460',N'GHIJKLMNOPQRSTU')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491081,N'D00708D1E1',N'OCIP',62554,'20100825 08:06:50.030',N'CDEFGHIJKLMNOPQ')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491082,N'D0070B7DFA',N'OCIP',62554,'20100825 08:11:13.507',N'VWXYZabcdefghij')
INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491083,N'D0070B7FCE',N'PRON_OCIP',62555,'20100825 09:13:26.563',N'XYZabcdefghijka')
...
more (30.000 rows)

您可以在這裡下載整批:https ://filebin.net/zg499h4iv1m44z6v

該表沒有索引、約束、外鍵、觸發器……什麼都沒有。

當我在本地SSMS 中執行批處理時,需要20 秒並產生這些等待統計資訊:

在此處輸入圖像描述

但是當我通過 LAN從遠端電腦在 SSMS 中執行它時,它需要100 秒(慢 5 倍),等待統計資訊幾乎相同:

在此處輸入圖像描述

請提及沒有 ASYNC_NETWORK_IO 等待類型。

SET NOCOUNT ON 不是故意設置的!

在其他環境中測試它工作得很好,時間沒有太大差異。

什麼可能是緩慢的真正根源?為什麼它沒有被等待統計數據擷取?請比僅僅說“網路基礎設施”更具體。

所以據我了解,這裡只涉及一個批次(SqlBatchCompleted)。假如說:

我的猜測是,差異是由於(缺乏)網路堆棧。

客戶端網路庫預設首先嘗試共享記憶體。這不會在網路堆棧中“下降”。這很可能是您最終從本地 SSMS 獲得的那個。

但是共享記憶體當然不能在遠端機器上工作。下一個嘗試是 TCP,它很可能是您最終從遠端 SSMS 獲得的那個(除非您重新配置該客戶端或重新配置 SQL 伺服器 - 兩者都不太可能)。

因此,您可以將使用共享記憶體區域的 netlib 與在兩個方向上通過網路堆棧的程式碼路徑並且由於介於兩者之間的網路具有頻寬和延遲的 netlib 進行比較。

你可以玩的東西包括:

  • 在本地執行時強制 TCP netlib(SSMS 客戶端連接對話框中的選項)。
  • 使用各種網路數據包大小(也可在 SSMS 連接對話框中使用)。
  • 與您的網路人員交談並嘗試使用巨型幀等。

我將該文件轉換為動態 SQL 批處理,將批處理髮送到 Azure SQL 數據庫需要 34 秒,並且沒有跟踪該時間的等待統計資訊。例如

   declare @sql nvarchar(max) = N'
   
   INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491073,N''D0058A79AE'',N''OCIP'',51849,''20100823 10:02:04.683'',N''TUVWXYZabcdefgh'')
   INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491074,N''D00559B4C4'',N''OCIP'',62488,''20100823 10:02:04.710'',N''CDEFGHIJKLMNOPQ'')
   INSERT dbo.TestInsert(Col1,Col2,Col3,Col4,Col5,Col6)VALUES(146491075,N''D005AB75B6'',N''OCIP'',52836,''20100823 10:05:17.070'',N''BCDEFGHIJKLMNOP'')
   . . .

但是我只需要 2 秒就可以從臨時表中下載批處理腳本。

與本地環境相比,它也可能需要更多的 CPU 時間(特別是如果它是一個 VM、啟用了 TDE 或具有較慢的 CPU),但看起來上傳可能是造成大部分差異的原因。

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