Sql-Server
批處理模式是否僅適用於 ColumnStore 索引上的 Agg 函式
Azure SQL 數據庫 - 標準版(S3 服務層)
為什麼批處理模式只在使用聚合函式時生效?
DROP TABLE IF EXISTS dbo.TransCS CREATE TABLE dbo.TransCS ( Col1 INT ,Col2 AS Col1*2 ) CREATE CLUSTERED COLUMNSTORE INDEX CS_TransCS on dbo.TransCS; WITH L0 AS(SELECT 1 AS c UNION ALL SELECT 1), L1 AS(SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B), L2 AS(SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B), L3 AS(SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B), L4 AS(SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B), L5 AS(SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B), Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5) INSERT INTO dbo.TransCS (Col1) SELECT TOP (1000000) n FROM Nums ORDER BY n;
插入 100 萬行
行處理
SELECT * FROM dbo.TransCS
批量處理
SELECT Col1, Col2, SUM(Col2)OVER () FROM dbo.TransCS
有沒有辦法在不使用 Agg 函式的情況下利用性能優勢?這方面的文件很薄。
背景
早在 2017 年 7 月,Niko就發布了關於 SQL Server 2017 變化的部落格
…在 SQL Server 2017 中,查詢優化器有一個內部優化,它將對具有列儲存索引的執行計劃應用全面優化,避免在行執行模式下執行它們的陷阱
在此之前,即使涉及列儲存對象,您也會獲得“瑣碎計劃”的行模式執行。
您分享的執行計劃顯示第一個查詢有這個問題,您可以在 XML 中確認:
StatementOptmLevel="TRIVIAL"
解決方法
解決此問題的一種方法,獲得全面優化,從而獲得批處理模式掃描,是添加一個不會影響結果的子查詢,如下所示:
SELECT * FROM dbo.TransCS WHERE (SELECT 1) = 1;
由於聚合函式,第二個查詢已經得到了全面優化。
為什麼會這樣?
對於為什麼會發生這種情況,唯一想到的是:
您的數據庫的兼容性級別為 130 或更低(這似乎不太可能,因為我可以在執行計劃中看到正在使用 140 基數估計器)
這是 Azure SQL 數據庫中的更改/回歸
- 執行計劃中指示的“內部版本”是
15.0.1100.504
,它看起來像 SQL Server 2019 內部版本號(這是有道理的,因為這是 Azure)。我沒有要測試的 2019 實例,但行為的變化也可能存在您可能希望在回饋站點上將此情況報告給 Microsoft 。