Eya*_*man 4 sql-server execution-plan columnstore query-performance
我们正在使用包含约 50M 记录的聚集列存储索引表,与使用相同的数据库架构和数据(刚刚导出和导入 bak 文件)在本地运行相比,在GCP云 sql 上运行时会遇到很大的性能下降。
使用下面的查询,我们发现GCP云sql( https://www.brentozar.com/pastetheplan/?id=ByexjqpCF )上的执行计划没有在索引扫描上使用projectId谓词,而是仅将其应用于进一步的过滤步骤。在本地运行时(https://www.brentozar.com/pastetheplan/?id=rJLO59pRK),谓词被推入索引扫描,从而减少扫描行数并提高性能。
造成这种差异的原因是什么?
SELECT YEAR(ReferenceDate) RefDateYear, MONTH(ReferenceDate) RefDateMonth,sum(diffsum) DiffSum
into #res
FROM Journal jp
WHERE jp.projectId='582b02e2-add0-4b50-94f7-4e7e07497cf6' AND ReferenceDate < '20220101' AND batch != 9998
GROUP BY YEAR(ReferenceDate), MONTH(ReferenceDate)
Run Code Online (Sandbox Code Playgroud)
另请参阅表架构:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Journal](
[id] [int] IDENTITY(1,1) NOT NULL,
[projectId] [uniqueidentifier] NOT NULL,
[diffSum] [money] NOT NULL,
[batch] [int] NOT NULL,
[referenceDate] [datetime2](7) NOT NULL,
...
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Journal] ADD CONSTRAINT [Journal_pkey] PRIMARY KEY NONCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE CLUSTERED COLUMNSTORE INDEX [CCI_journal] ON [dbo].[Journal] WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
SQL Server 标准版有许多与列存储性能相关的限制。
1内存中 OLTP 数据大小和列存储段缓存仅限于“规模限制”部分中的版本指定的内存量。批处理模式操作的并行度 (DOP)对于 SQL Server Standard Edition 限制为 2,对于 SQL Server Web 版和 Express Edition 限制为 1。这是指在基于磁盘的表和内存优化表上创建的列存储索引。
2聚合下推、字符串谓词下推和 SIMD 优化是 SQL Server 企业版可扩展性增强功能
来自列存储索引 - 新增功能 - 数据库兼容性级别 120 或 130 的性能:
- 字符串谓词下推可加快比较 VARCHAR/CHAR 或 NVARCHAR/NCHAR 类型字符串的查询速度。这适用于常见的比较运算符,并包括使用位图过滤器的 LIKE 等运算符。这适用于所有支持的排序规则。在 SQL Server 上,此增强功能是为企业版保留的。
尽管您的谓词是 UUID,但它在这里算作字符串谓词。如果没有字符串谓词下推,谓词将在单独的 Filter 中求值,无需特殊优化。
列存储索引 - 查询性能文档中对字符串谓词下推有更全面的描述。
字符串谓词下推利用为列创建的主/辅字典来提高查询性能。例如,让我们考虑由 100 个不同字符串值组成的行组中的字符串列段。这意味着假设有 100 万行,每个不同的字符串值平均被引用 10,000 次。
通过字符串谓词下推,查询执行会根据字典中的值计算谓词,如果它符合条件,则引用字典值的所有行都会自动符合条件。这通过两种方式提高了性能:
仅返回符合条件的行,减少需要流出 SCAN 节点的行数。
字符串比较的次数显着减少。在此示例中,仅需要 100 次字符串比较,而需要进行 100 万次比较。有一些限制,如下所述:
- 增量行组没有字符串谓词下推。增量行组中的列没有字典。
- 如果字典超过 64 KB 条目,则不会进行字符串谓词下推。
- 不支持计算 NULL 的表达式。
查看标准版中的列存储有多有用?Erik Darling 的其他例子。
归档时间: |
|
查看次数: |
403 次 |
最近记录: |