應用程式常犯錯誤:使用非參數化的特設查詢而非準備好的查詢或預存程序。這會導致 SQL Server 計畫快取中累積大量無法重用的執行計畫。
計畫快取位於共享記憶體池,儲存解析、編譯、優化後的查詢執行計畫。重用計畫可節省 CPU 密集型工作(解析、編譯、優化),降低回應時間與 CPU 壓力。
Java 程式迴圈執行 20 筆非參數化查詢:
String sql = "SELECT * FROM SalesOrderHeader WHERE SalesOrderID = " + id;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
查詢 sys.dm_exec_cached_plans 發現每次執行都產生一個具體、無參數化的計畫,usecounts = 1,幾乎無法重用。高頻應用下記憶體會迅速耗盡。
SELECT qs.usecounts, cacheobjtype, objtype, qt.text
FROM sys.dm_exec_cached_plans qs
CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) AS qt
ORDER BY qt.text;