開發測試階段常需快速產生大量模擬資料以驗證分頁、索引、鎖定等效能表現。純 T-SQL 迴圈插入雖簡單,但逐筆 INSERT 效能極差。本文介紹三種進階批次插入技巧,效能提升百倍以上。
DECLARE @i INT = 1;
WHILE @i <= 1000000
BEGIN
INSERT INTO manager (username, userpwd) VALUES ('kgdiwss', '250');
SET @i += 1;
END
缺點:每筆觸發交易、寫入交易記錄、更新索引,100 萬筆約需 30~60 分鐘。
INSERT INTO manager (username, userpwd)
SELECT TOP 1000000 'user_' + CAST(ROW_NUMBER() OVER (ORDER BY a.id) AS VARCHAR), 'pwd123'
FROM sysobjects a CROSS JOIN sysobjects b CROSS JOIN sysobjects c;
原理:sysobjects 約 2,000 列,三重 CROSS JOIN 產生 80 億列,TOP 截取所需筆數,ROW_NUMBER() 產生唯一流水號。單一陳述式、單一交易、最小化記錄。
| 方法 | 耗時 | 交易記錄增長 | 備註 |
|---|---|---|---|
| WHILE 迴圈 | 42 分 | 1.2 GB | 逐筆 COMMIT |
| 單一 INSERT + CROSS JOIN | 18 秒 | 45 MB | 最小化記錄(簡單復原模式) |
| BCP 匯入文字檔 | 12 秒 | 38 MB | 需外部檔案、最快 |
data.txtuser_1 pwd123
user_2 pwd123
...
user_1000000 pwd123
可用簡單腳本(Python/PowerShell/VBS)快速產生。
bcp testdb.dbo.manager in data.txt -c -t"\t" -Slocalhost -Usa -Ppassword -b10000 -h"TABLOCK"
參數說明:-b10000 批次大小 10,000 筆;-h"TABLOCK" 取得表級鎖定,最小化記錄;-c 字元模式。
SIMPLE 或 BULK_LOGGED,避免交易記錄暴增;DROP INDEX,匯入後重建,比維護即時索引快 10 倍以上;ALTER TABLE ... NOCHECK CONSTRAINT ALL 暫停檢查,匯入後 CHECK CONSTRAINT ALL 重新驗證;TABLOCK 配合 MAXDOP 實現平行插入。「用 SQL 寫迴圈插入」是新手常見誤區。SQL Server 專為集合操作設計,善用 CROSS JOIN 產生數列、BCP 批次匯入、最小化記錄 三大技巧,百萬筆資料從「喝杯咖啡等」變成「眨眼間完成」。實務上建議:測試資料產生腳本化、參數化,納入自動化部署流程。