需快速測量單條 SQL 執行耗時(含編譯、優化、執行、網絡往返),無需開啟 Profiler/擴展事件。本文提供最輕量的 T-SQL 計時模板,適用於即時調優驗證。
標準計時模板
DECLARE @StartTime DATETIME2(7) = SYSUTCDATETIME(); -- 高精度 UTC 時間
-- 待測試語句
SELECT * FROM LargeTable WHERE Col1 = 'FilterValue' ORDER BY Col2;
SELECT DATEDIFF(MILLISECOND, @StartTime, SYSUTCDATETIME()) AS ElapsedMs;
進階:多次執行取平均(消除冷啟動/緩存影響)
DECLARE @Iterations INT = 10, @i INT = 0, @TotalMs BIGINT = 0;
DECLARE @StartTime DATETIME2(7);
WHILE @i < @Iterations
BEGIN
SET @StartTime = SYSUTCDATETIME();
-- 待測語句
SELECT * FROM LargeTable WHERE Col1 = 'FilterValue';
SET @TotalMs += DATEDIFF(MILLISECOND, @StartTime, SYSUTCDATETIME());
SET @i += 1;
-- 可選:清理緩存模擬冷啟動(謹慎用於生產)
-- DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
END
SELECT @TotalMs / @Iterations AS AvgElapsedMs, @Iterations AS Runs;
關鍵函數對比
| 函數 | 精度 | 返回類型 | 推薦場景 |
GETDATE() | ~3.33 ms | DATETIME | 粗略估算、兼容老版本 |
SYSDATETIME() | 100 ns | DATETIME2(7) | 高精度計時、審計時間戳 |
SYSUTCDATETIME() | 100 ns | DATETIME2(7) | 跨時區一致、推薦計時基準 |
DATEDIFF(MILLISECOND, ...) | 1 ms | INT | 毫秒級差值 |
DATEDIFF_BIG(MICROSECOND, ...) | 1 μs | BIGINT | 微秒級差值 (2016+) |
注意事項
- 包含網絡往返:SSMS 執行耗時 = 網絡延遲 + 服務端執行 + 結果傳輸 + 客戶端渲染。純服務端耗時需看
SET STATISTICS TIME ON 輸出的 CPU time / Elapsed time。
- 首次執行偏高:編譯優化、數據頁讀入緩存,建議預熱 1-2 次後再計時。
- 並發干擾:生產環境並發負載下單次測量波動大,多次取中位數更穩健。
- 不可用於函數/觸發器內:上下文限制,需在批次/存儲過程頂層使用。
對比:專業級計時工具
| 工具 | 維度 | 優點 | 缺點 |
| SET STATISTICS TIME/IO ON | 編譯/執行 CPU、邏輯/物理讀、掃描計數 | 服務端純粹、無網絡干擾、官方標準 | 輸出混在結果中、需解析 |
| Extended Events (sql_statement_completed) | 全維度、生產級、持久化、可過濾 | 零侵入、歷史追溯、聚合分析 | 配置較繁瑣、需權限 |
| Query Store (2016+) | 歷史計劃、執行統計、退化檢測 | 自動收集、圖形化、強制計劃 | 佔用存儲、需啟用 |
| 本文模板 | 毫秒級壁鐘時間 | 零配置、即時、可嵌入腳本/存儲過程 | 含網絡/客戶端、單點采樣 |
總結
DECLARE @t DATETIME2 = SYSUTCDATETIME(); ... SELECT DATEDIFF(MS, @t, SYSUTCDATETIME()); 是「隨手可用」的計時利器。調優閉環建議:模板快速驗證 → STATISTICS TIME 精確拆解 → Query Store 歷史趨勢 → Extended Events 生產全景,四層工具疊加,從點到面構建完整性能可觀測體系。
- 上一篇文章: SQL Server PRINT 語句導致客戶端異常斷開的離奇案例與最佳實踐
- 下一篇文章: PL/SQL 實現 Oracle 任務調度與閃回查詢:DBMS_JOB 與 DBMS_FLASHBACK 實戰
Copyright ©
程式碼之家 All Rights Reserved