gpt4 book ai didi

sql-server - SQL Server 如何计算出估计的行数?

转载 作者:行者123 更新时间:2023-12-02 22:32:28 25 4
gpt4 key购买 nike

我正在尝试调试一个相当复杂的存储过程,该存储过程连接多个表(10-11)。我发现对于树的一部分,估计的行数与实际的行数有很大不同 - 在最坏的情况下,SQL Server 估计将返回 1 行,而实际上返回了 55,000 行!

我正在尝试找出原因 - 我的所有统计数据都是最新的,并且我已经使用几个表上的 FULLSCAN 更新了统计数据。我没有使用任何用户定义的函数或表变量。据我所知,SQL Server 应该能够准确估计将返回多少行,但它继续选择一个计划,在这种情况下它会执行数万次 RDI 查找(当它预计只执行 1 次时)或 2)。

我可以做什么来尝试理解为什么估计行数超出这么多?

更新:因此,查看该计划,我发现了一个特别可疑的节点 - 它使用以下谓词对表进行表扫描:

status <> 5
AND [type] = 1
OR [type] = 2

此谓词返回整个表(630 行 - 表扫描本身并不是性能不佳的根源),但是 SQL Server 的估计行数仅为 37。然后 SQL Server 继续执行几个嵌套循环这涉及 RDI 查找、索引扫描和索引查找。难道这就是我严重误判的根源吗?如何让它估计更合理的行数?

最佳答案

SQL Server 将每个索引拆分为最多 200 个范围,其中包含以下数据(来自 here):

  • RANGE_HI_KEY

    A key value showing the upper boundary of a histogram step.

  • RANGE_ROWS

    Specifies how many rows are inside the range (they are smaller than this RANGE_HI_KEY, but bigger than the previous smaller RANGE_HI_KEY).

  • EQ_ROWS

    Specifies how many rows are exactly equal to RANGE_HI_KEY.

  • AVG_RANGE_ROWS

    Average number of rows per distinct value inside the range.

  • DISTINCT_RANGE_ROWS

    Specifies how many distinct key values are inside this range (not including the previous key before RANGE_HI_KEY and RANGE_HI_KEY itself);

通常,大多数填充值都会进入 RANGE_HI_KEY

但是,它们可能会进入该范围,这可能会导致分布倾斜。

想象一下这些数据(以及其他数据):

键值行数

1          1
2 1
3 10000
4 1

SQL Server 通常构建两个范围:134 到下一个填充值,这进行这些统计:

RANGE_HI_KEY  RANGE_ROWS  EQ_ROWS  AVG_RANGE_ROWS  DISTINCT_RANGE_ROWS
3 2 10000 1 2

,这意味着当搜索2时,只有1行,最好使用索引访问。

但是如果 3 进入该范围,统计数据如下:

RANGE_HI_KEY  RANGE_ROWS  EQ_ROWS  AVG_RANGE_ROWS  DISTINCT_RANGE_ROWS
4 10002 1 3334 3

优化器认为键 23334 行,并且索引访问成本太高。

关于sql-server - SQL Server 如何计算出估计的行数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1476723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com