Sql-Server

批處理模式是否僅適用於 ColumnStore 索引上的 Agg 函式

  • February 20, 2019

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 。

引用自:https://dba.stackexchange.com/questions/230121