AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 174249
Accepted
John Eisbrener
John Eisbrener
Asked: 2017-05-23 12:17:07 +0800 CST2017-05-23 12:17:07 +0800 CST 2017-05-23 12:17:07 +0800 CST

为什么 Parallelism (Repartition Streams) Operator 会将 Row Estimates 减少到 1?

  • 772

我正在使用 SQL Server 2012 企业版。我遇到了一个 SQL 计划,它表现出一些我不觉得完全直观的行为。在大量并行索引扫描操作之后,发生并行(重新分区流)操作,但它正在杀死索引扫描(Object10.Index2)返回的行估计,将估计减少到 1。我做了一些搜索,但是没有遇到任何解释这种行为的东西。查询非常简单,尽管每个表都包含数百万的记录。这是 DWH 加载过程的一部分,这个中间数据集在整个过程中被触及了几次,但我遇到的问题尤其与行估计有关。有人可以解释为什么在 Parallelism (Repartition Strems) Operator 中准确的行估计会变为 1 吗?还,

我已将完整计划发布到粘贴计划。

这是有问题的操作:

在此处输入图像描述

包括计划树以防添加更多上下文:

在此处输入图像描述

我会遇到 Paul White 提交的这个 Connect 项目的一些变体吗(在他的博客上进一步深入解释)?至少它是我发现的唯一一个似乎与我遇到的情况很接近的东西,即使没有 TOP 操作员在玩。

sql-server sql-server-2012
  • 3 3 个回答
  • 8962 Views

3 个回答

  • Voted
  1. Best Answer
    Joe Obbish
    2017-05-23T16:57:55+08:002017-05-23T16:57:55+08:00

    带有位图过滤器的查询计划有时难以阅读。来自重新分区流的 BOL 文章(强调我的):

    Repartition Streams 运算符使用多个流并生成多个记录流。记录内容和格式不变。如果查询优化器使用位图过滤器,则输出流中的行数会减少。

    此外,关于位图滤镜的文章也很有帮助:

    在分析包含位图过滤的执行计划时,了解数据如何在计划中流动以及应用过滤的位置非常重要。位图过滤器和优化位图是在哈希连接的构建输入(维度表)一侧创建的;但是,实际过滤通常在 Parallelism 运算符中完成,该运算符位于散列连接的探测输入(事实表)一侧。但是,当位图过滤器基于整数列时,过滤器可以直接应用于初始表或索引扫描操作,而不是并行操作符。这种技术称为行内优化。

    我相信这就是您在查询中观察到的。可以提出一个相对简单的演示来显示重新分区流运算符减少基数估计,即使位图运算符IN_ROW与事实表相反。资料准备:

    create table outer_tbl (ID BIGINT NOT NULL);
    
    INSERT INTO outer_tbl WITH (TABLOCK)
    SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM master..spt_values;
    
    create table inner_tbl_1 (ID BIGINT NULL);
    create table inner_tbl_2 (ID BIGINT NULL);
    
    INSERT INTO inner_tbl_1 WITH (TABLOCK)
    SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2;
    
    INSERT INTO inner_tbl_2 WITH (TABLOCK)
    SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2;
    

    这是您不应该运行的查询:

    SELECT *
    FROM outer_tbl o
    INNER JOIN inner_tbl_1 i ON o.ID = i.ID
    INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
    OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);
    

    我上传了计划。看看附近的运营商inner_tbl_2:

    重新分区丢失行

    您还可能会发现Paul White在Hash Joins on Nullable Columns中的第二个测试很有帮助。

    在如何应用行缩减方面存在一些不一致。我只能在至少有三张桌子的计划中看到它。但是,使用正确的数据分布,预期行数的减少似乎是合理的。假设事实表中的连接列有许多在维度表中不存在的重复值。位图过滤器可能会在这些行到达连接之前消除它们。对于您的查询,估计值一直减少到 1。行在散列函数中的分布方式提供了一个很好的提示:

    行发行版

    基于此,我怀疑您的Object1.Column21列有很多重复值。如果重复的列碰巧不在统计直方图中,Object4.Column19那么 SQL Server 可能会得到非常错误的基数估计。

    我认为您应该担心可能会提高查询的性能。当然,如果查询满足响应时间或 SLA 要求,则可能不值得进一步调查。但是,如果您确实希望进一步调查,您可以做一些事情(除了更新统计信息)来了解如果查询优化器有更好的信息,它是否会选择更好的计划。您可以将连接的结果Database1.Schema1.Object10放入Database1.Schema1.Object11临时表中,然后查看是否继续获得嵌套循环连接。您可以将该连接更改为 a LEFT OUTER JOIN,这样查询优化器就不会在该步骤减少行数。您可以MAXDOP 1在查询中添加提示以查看会发生什么。你可以使用TOP连同派生表一起强制连接到最后,或者您甚至可以从查询中注释掉连接。希望这些建议足以让您入门。

    关于问题中的连接项,它与您的问题有关的可能性极小。这个问题与糟糕的行估计无关。它与并行的竞争条件有关,导致在后台的查询计划中处理太多行。在这里,您的查询似乎没有做任何额外的工作。

    • 9
  2. Paul White
    2017-05-24T02:45:43+08:002017-05-24T02:45:43+08:00

    这里的核心问题是对第一次连接结果的基数估计很差。这可能由于许多原因而出现,但最常见的情况是统计数据过时或一些相关的连接谓词,优化器的默认模型假定它们是独立的。

    在后一种情况下,修复:在 SQL Server 2008 或 SQL Server 2008 R2 或 SQL Server 2012 中运行包含相关 AND 谓词的查询时性能不佳可能与使用支持的跟踪标志 4137 相关。您也可以尝试使用查询跟踪标志 4199 以启用优化器修复,和/或 2301 以启用建模扩展。根据匿名计划很难知道。

    位图的存在不会直接影响连接的基数估计,但它确实通过应用早期半连接减少使其效果更快可见。如果没有位图,第一次连接的基数估计将是相同的,并且计划的其余部分仍将相应地进行优化。

    如果您好奇,在测试系统上,您可以使用跟踪标志 7498 禁用查询的位图。您还可以禁用优化位图(由优化器考虑并影响基数估计),用优化后位图替换它们(不考虑由优化器,对基数没有影响)与跟踪标志 7497 和 7498 的组合。两者都没有记录或支持在生产系统上使用,但它们确实产生优化器可以正常考虑的计划,因此可以强制使用计划指南。

    这些都不能解决上面提到的第一次加入估计差的核心问题,所以我真的只是为了利益着想。

    进一步阅读位图和哈希连接:

    • Bitmap Magic(或……SQL Server 如何使用位图过滤器)由我
    • Craig Freedman 的Parallel Hash Join
    • SQL Server 查询处理团队的查询执行位图
    • 解释在线书籍中包含位图过滤器的执行计划
    • 了解联机丛书中的哈希联接
    • 6
  3. SQLBek
    2017-05-23T13:48:26+08:002017-05-23T13:48:26+08:00

    在 Twitter 上回复了你。我查看了附加的 XML,发现并行性不平衡。1 个线程几乎包含所有实际行,而其他大多数线程都没有。尖叫不平衡的并行性正在发生。因此,我会研究键/连接值及其各自的统计数据和基数。

    根据您的其他想法,我不太确定 Connect 项是否适用,因为您粘贴的计划在我看到的任何地方都不包含 TOP。

    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve