SQL Server:在左连接查询的执行计划中插入隐藏的“排序”

Posted

技术标签:

【中文标题】SQL Server:在左连接查询的执行计划中插入隐藏的“排序”【英文标题】:SQL Server: hidden "Sort" inserted in execution plan in left join query 【发布时间】:2019-09-14 10:53:45 【问题描述】:

SQL 2017 标准 我在星型模式模型(数据仓库)中有一个数据库 为了填写事实表,我有一个存储过程,其中包含一个大约 470,0000 行的临时表。 为了填写维度 ID,我在临时表和维度表之间进行了左连接操作。 例如:

insert into factTable (...fields list...)
select t.Quantity1,t.Quantity2,d1.ID,d.ID,...,19.id from
MyTemp t
left outer join dim1 d1 on t.F1=d1.F1 and t.CompanyID=d1.CompanyID and t.DataSourceID=d1.DataSourceID
left outer join dim2 d2 on t.F2=d2.F2 and t.CompanyID=d2.CompanyID and t.DataSourceID=d2.DataSourceID
left outer join dim3 d3 on t.F3=d3.F3 and t.CompanyID=d2.CompanyID and t.DataSourceID=d2.DataSourceID
.......
left outer join dim19 d19 on t.F19=3.F19 and t.CompanyID=d19.CompanyID and t.DataSourceID=d19.DataSourceID

问题是当使用较少数量的连接时,例如前 5 或 6 个维度,查询非常快。

有 19 个连接,需要 4 个多小时。

执行计划显示瓶颈来自查询优化器插入的隐藏“排序”操作!!!!

当从每个维度读取数据时,sql server 在加入临时表之前对维度数据进行排序。 在临时表上引入索引并没有解决问题。 即使将查询限制在临时表索引中的第一个字段也无济于事

【问题讨论】:

能否为维度表添加DDL,包括索引? 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。对于包含 DBMS/产品和 DDL 的 SQL,其中包括约束和索引以及表格格式的基表初始化。对于包括 EXPLAIN 结果和统计信息的 SQL 性能。 (约束、索引和计划对性能至关重要。) PS 请使用标准标点符号。对于可以作为文本给出的内容,请使用文本。用图像增强。 DBMS 排序或索引以避免比较连接的每个表中的所有行对。 嗨,大卫。我目前无权访问部署它的服务器。将在这个星期一早上尽快发布。感谢您的关注。抱歉耽搁了,但我会尽快发布信息,因为这对我来说非常重要。再次感谢。 【参考方案1】:

使用

CREATE CLUSTERED COLUMNSTORE INDEX

临时表解决了这个问题。 谢谢你们。 您可以查看CLUSTERED COLUMNSTORE INDEX了解更多详情 (如果您使用的是 SQL Server 2016 标准版,则需要 SP2)

【讨论】:

以上是关于SQL Server:在左连接查询的执行计划中插入隐藏的“排序”的主要内容,如果未能解决你的问题,请参考以下文章

强制SQL Server执行计划使用并行提升在复杂查询语句下的性能

如何将在左连接中具有连接的 sql 转换为查询构建器?

执行真实计划 SQL Server

Sql Server中执行计划的缓存机制

SQL查询语句的执行

SQL Server - 条件语句的查询执行计划