Does Batch Mode only apply to Agg Functions on ColumnStore Index
Question
Azure SQL Database - Standard Edition (S3 Service Tier)
Why does Batch Mode only come into effect when using Aggregate Functions?
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;
Insert 1 Million rows
Row Processing
SELECT * FROM dbo.TransCS
Batch Processing
SELECT Col1, Col2, SUM(Col2)OVER ()
FROM dbo.TransCS
Is there a way to utilise the performance benefits without using Agg functions? Documentation on this is thin.
Solution
Background
Back in July 2017, Niko blogged about a change in SQL Server 2017
...in SQL Server 2017 there is an internal optimisation for the Query Optimiser, that shall apply FULL optimisation to the execution plans with the Columnstore Indexes, avoiding the pitfall of executing them in the Row Execution Mode
Prior to that, you would get row-mode execution for "trivial plans," even when there were columnstore objects involved.
The execution plan you shared shows that the first query has this problem, which you can confirm in the XML:
StatementOptmLevel="TRIVIAL"
Workaround
One way to work around this, get FULL optimization, and thus get a batch mode scan, is to add a subquery that won't affect your results, like this:
SELECT * FROM dbo.TransCS WHERE (SELECT 1) = 1;
The second query gets full optimization already because of the aggregate function.
Why is this happening?
The only things that come to mind for why this might happen are:
- your database has a compatability level of 130 or lower (this seems unlikely because I can see in the execution plan that the 140 cardinality estimator is being used)
- this is a change / regression in Azure SQL Database specifically
- The "build" indicated in the execution plan is
15.0.1100.504
, which looks like a SQL Server 2019 build number (which makes sense, since this is Azure). I don't have a 2019 instance to test on, but the change in behavior might be there as well
- The "build" indicated in the execution plan is
You may want to report this to Microsoft on the feedback site.