【发布时间】:2017-06-25 15:04:57
【问题描述】:
当我执行涉及以下 3 个表的 SQL 语句时,我遇到了严重的性能问题:
表A表C
特别是,这些表在数据仓库中,中间的表是维度表,而其他表是事实表。 TableA 大约有 900 万条记录,而 TableC 大约有 300 万条记录。维度表(TableB)只有74条记录。
查询的语法很简单,可以看到,其中TableA叫_PG,TableB等于_MDT,Table C叫_FM:
SELECT _MDT.codiceMandato as Customer, SUM(_FM.Totale) AS Revenue,
SUM(_PG.ErogatoTotale) AS Paid
FROM _PG INNER JOIN
_MDT
ON _PG.idMandato = _MDT.idMandato INNER JOIN
_FM
ON _FM.idMandato = _MDT.idMandato
GROUP BY _MDT.codiceMandato
实际上,我从未见过这个查询的结尾 :-( _PG 在 idMandato 和同一个 _FM 表上有一个非聚集索引 _MDT 表在 idMandato 上有一个聚集索引
执行计划如下
正如您所见,瓶颈是由于 Stream Aggregate(成本的 33%)和 Merge Join(成本的 66%)造成的。特别是,流聚合强调了大约 4000 亿的估计行! 我不知道原因,也不知道如何解决这个糟糕的问题。 我使用 SQL Server 2016 SP1 安装的虚拟服务器,Windows Server 2012 Standard 具有 4 个 Cpu 核心和 32 GB 的 RAM,1,5TB 在由具有 SSD 缓存的 SAS 磁盘组成的专用卷上。 希望有人能帮我理解。
提前致谢
【问题讨论】:
-
编辑您的问题并提供示例数据和所需的结果。目前尚不清楚您的表格到底是什么样子。
-
尝试将
Totale和ErogatoTotale添加为非聚集索引的包含列。 -
估计可能是正确的 :-) 在两个事实表中,
idMandato可能非常不唯一,而您实际上执行了 M:N-join。根据您的实际问题,您可以在连接之前使用 CTE/派生表对每个事实表求和。 -
表1:N----1:1-----1:N之间的关系遵循星型模式。
标签: sql sql-server performance join data-warehouse