问题描述
其中一个突触表,我们有 3 亿行,并且还在不断增加。每行作为状态列,即 active_row 为 0 或 1。 Active_row 是 int 数据类型。用户仅查询基于 active_row = 1,其中只有 2800 万行和其余数据,即 2.7 亿处于非活动状态。 为了提高性能并避免在 active_row 上进行全表扫描,我将 active_row 上的分区表中的表转换如下
CREATE TABLE [repo].[STXXXXX]
WITH
(
disTRIBUTION = ROUND_ROBIN,CLUSTERED INDEX (
[ID] ASC
),PARTITION
(
active_Row RANGE LEFT FOR VALUES (0,1)
)
)
as
select * from repo.nonptxx;
用户报告移动到分区表后没有性能提升。当我检查以下查询时,即分区与非分区,我没有看到查询解释有任何差异,即估计的子树、操作等,并且所有统计数据都保持不变。从 sys.dm_pdw_nodes_db_partition_stats 我可以看到在分区 1 上创建了 3 个分区,其中 2.7 亿个数据溢出到 60 个节点中,60 个节点中的第 2 个分区溢出了 3000 万个,60 个节点中的第 3 个是空的。
select * from [repo].[STXXXXX] where active_row =1
对比
select * from repo.nonptxx where active_row =1
请告知是什么问题,为什么移入分区表后没有改善以及如何调整?
解决方法
统计数据是否更新?
运行 UPDATE STATISTICS [schema_name].[table_name] 并重新运行您的测试(如果不存在,则创建 Stats)。
在 Get 步骤之后查询 tsql 查询计划中的单个分区时,您应该会看到一个过滤步骤,其中返回的行数较少。您不会在 dsql 查询计划中看到它。您不会看到 Select * 的任何子树成本,这会转换为来自各个节点的单个 Return 操作,但是您会看到每次执行的估计行数随着您按分区过滤而变小(使用最新的统计数据) .缺少或过时的统计信息可能会产生一些奇怪的查询计划结果,因为优化器基本上没有足够的信息来做出正确的决定......因此结果不可预测,有时甚至是糟糕的结果。
如果它不能为您提供所需的性能,您可能需要考虑的另一个选项是保留没有分区的数据,并简单地在列上创建一个非聚集索引。索引并不总是被使用或表现得完全符合您对 SQL 服务器的期望,但是在这种用例中,通常一列索引将极大地帮助性能。使用索引的好处是,如果您的数据从活动移动到非活动,则不需要在物理分区之间移动记录。