微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – 是否可以强制优化器消除此分区视图中不相关的表?

我正在为大型表测试不同的体系结构,并且我看到的一个建议是使用分区视图,其中大表被分成一系列较小的“分区”表.

1,2,3,4

在测试这种方法时,我发现了一些对我来说没有多大意义的东西.当我在事实视图上过滤“分区列”时,优化器仅搜索相关表.此外,如果我在维度表上过滤该列,则优化程序会删除不必要的表.

但是,如果我过滤维度的某些其他方面,则优化程序会查找每个基表的PK / CI.

以下是有问题的查询

select 
    od.[Year],AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where o.ObservationDateKey >= 20000101
    and o.ObservationDateKey <= 20051231
group by od.[Year];

select 
    od.[Year],AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.DateKey >= 20000101
    and od.DateKey <= 20051231
group by od.[Year];

select 
    od.[Year],AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.[Year] >= 2000 and od.[Year] < 2006
group by od.[Year];

Here’s a linksql Sentry Plan Explorer会话.

我正在研究实际上对较大的表进行分区,以查看是否可以以类似的方式响应分区.

我确实获得了对维度的一个方面进行过滤的(简单)查询的分区消除.

在此期间,这是一个仅限统计数据的数据库副本:

https://gist.github.com/swasheck/9a22bf8a580995d3b2aa

“旧的”基数估算器获得了一个更便宜的计划,但这是因为每个(不必要的)索引搜索的基数估计值较低.

我想知道是否有一种方法可以让优化器在按维度的另一个方面进行过滤时使用密钥列,以便它可以消除对不相关表的搜索.

sql Server版本:

Microsoft sql Server 2014 - 12.0.2000.8 (X64) 
    Feb 20 2014 20:04:26 
    copyright (c) Microsoft Corporation
    Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)

解决方法

启用跟踪标志4199.

我还必须发出:

UPDATE STATISTICS dbo.ObservationDates 
WITH ROWCOUNT = 73049;

获得下面显示的计划.上传时缺少此表的统计信息. 73,049这个数字来自Plan Explorer附件中的Table Cardinality信息.我使用sql Server 2014 SP1 CU4(内部版本12.0.4436)和两个逻辑处理器,最大内存设置为2048 MB,除了4199之外没有跟踪标志.

然后,您应该获得具有动态分区消除功能的执行计划:

select 
    od.[Year],AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where 
    od.[Year] >= 2000 and od.[Year] < 2006
group by 
    od.[Year]
option (querytraceon 4199);

计划片段:

这看起来可能更糟,但过滤器都是启动过滤器.示例谓词是:

每次迭代循环时,都会测试启动谓词,并且只有当它返回true时才会执行下面的Clustered Index Seek.因此,动态分区消除.

这可能不如静态消除那么有效,特别是如果计划是平行的.

您可能需要在视图上尝试MAXDOP 1,FAST 1或FORCESEEK等提示以获得相同的计划.分区视图(如分区表)的优化程序成本选择可能很棘手.

关键是您需要一个具有启动过滤器的计划,以通过分区视图来消除动态分区.

使用嵌入式USE PLAN提示查询:(通过gist.github.com):

> Serial plan
> Parallel plan

原文地址:https://www.jb51.cc/mssql/79776.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐