SQL Server 可以並行執行兩個 BULK INSERT 嗎?
我有兩個繁重的查詢要執行,它們都需要大約 1 分鐘才能執行。這兩個查詢都使用批量插入命令將文本文件中的數據插入到數據庫中的表中。
對於導入數據的兩個表,沒有索引/觸發器/約束,只有兩個空表可以載入數據。
對於要載入的兩個文本文件,它們每個都有大約 20M 行。
查詢一:
Bulk insert table1 FROM 'table1.txt' WITH (FIELDTERMINATOR ='|', ROWTERMINATOR = '0x0a', TABLOCK)
查詢 2:
Bulk insert table2 FROM 'table2.txt' WITH (FIELDTERMINATOR ='|', ROWTERMINATOR = '0x0a', TABLOCK)
我想比較不同場景下的執行時間。
場景 1:兩個查詢在一個編輯器中串列執行:
- 查詢 1:1 m 18 s
- 查詢 2:1 m 2 s
- 總執行時間為2m 20s。
場景 2:同一Studio 實例的單獨編輯器中的每個查詢,同時執行:
- 查詢 1:2 m 36 s
- 查詢 2:2 m 09 d
- 總執行時間為2m 40s
場景 3:每個查詢在一個單獨的Studio 實例中,同時執行:
- 查詢 1:2 m 29 s
- 查詢 2:2 m 19 s
- 總執行時間為2m 29s
雖然場景 2 和 3 似乎同時執行查詢,但為什麼執行時間沒有太大變化?對於所有場景,CPU 使用率在 17% 到 21% 之間,磁碟使用率在 50MB 到 70MB 每秒。沒有觀察到 CPU 和磁碟使用率之間的顯著差異。
我想知道引擎蓋下發生了什麼?SQL Server 如何執行這些查詢?為什麼所有三種場景的執行時間幾乎相同?有什麼辦法可以加快速度嗎?
我在 Windows 10 64 位上使用 SQL Server 2016 Developer Edition。我的筆記型電腦中有四核 i7 和 SSD。
在測試了 4 個查詢一起執行的更多場景後,我認為 CPU 和磁碟使用率低的可能原因是我的 Core i7 的超執行緒:
- 兩個編輯器同時執行兩個查詢,最多的 CPU 使用率為 25%。
- 4 個編輯器同時執行 4 個查詢,最多 CPU 使用率為 50%。
你們知道讓一個查詢專門使用一個核心的方法嗎?關閉超執行緒對我來說不是一個選項,因為我的 ThinkPad T460p 在 BIOS 中不支持這樣的選項。
在這個 MSDN 論壇主題中與 Dan Guzman 進行了長時間且有益的討論後,我終於清楚了底層調度方案。這是從上面的執行緒中藉用的一個簡短答案:
所以這裡發生的是 2 個 SSMS 連接最初都使用相同的調度程序,因為它的負載最少。BULK INSERT 然後都在同一個調度程序上執行,這就是高 SOS_SCHEDULER_YIELD 等待的原因。
使用哪個調度程序的選擇不是基於查詢成本。SQL Server(實際上是 SOS)基本上試圖通過檢查sys.dm_os_schedulers的 load_factor 列來平衡調度程序之間的工作負載。
當為查詢執行創建新任務時,SOS 更喜歡使用與會話上的最後一個請求相同的調度程序。但是,如果首選調度器的負載因子大於其他調度器平均負載因子的某個百分比,它將使用不同的調度器。
深入討論可以在上面的連結中找到。
感謝所有小伙伴的熱心幫助!