相关疑难解决方法(0)

SQL Server 的优化器如何估计联接表中的行数?

我在AdventureWorks2012数据库中运行此查询:

SELECT 
    s.SalesOrderID,
    d.CarrierTrackingNumber,
    d.ProductID,
    d.OrderQty
FROM Sales.SalesOrderHeader s 
JOIN Sales.SalesOrderDetail d 
    ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077
Run Code Online (Sandbox Code Playgroud)

如果我查看估计的执行计划,我会看到以下内容:

在此处输入图片说明

初始索引查找(右上角)使用 IX_SalesOrderHeader_CustomerID 索引并搜索文字 11077。它估计有 2.6192 行。

在此处输入图片说明

如果我使用DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM,则显示值 11077 介于两个采样键 11019 和 11091 之间。

在此处输入图片说明

11019 和 11091 之间不同行的平均数为 2.619718,或四舍五入为 2.61972,这是为索引查找显示的估计行的值。

我不明白的部分是针对 SalesOrderDetail 表的聚集索引查找的估计行数。

在此处输入图片说明

如果我运行DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID')

在此处输入图片说明

所以 SalesOrderID(我正在加入)的密度是 3.178134E-05。这意味着 1/3.178134E-05 (31465) 等于 SalesOrderDetail 表中唯一 SalesOrderID 值的数量。

如果 SalesOrderDetail 中有 31465 个唯一的 SalesOrderID,那么在均匀分布的情况下,每个 SalesOrderID 的平均行数为 121317(总行数)除以 31465。平均值为 3.85561

因此,如果估计要循环的行数是 …

sql-server optimization execution-plan sql-server-2012 cardinality-estimates query-performance

13
推荐指数
1
解决办法
2734
查看次数

在 SQL Server 中应用基数估计问题

现在,我面临着基数估计的逻辑问题,这个问题在一个看似相当简单的情况下对我来说不是很清楚。我在工作中遇到过这种情况,因此出于隐私考虑,下面仅对问题进行一般性描述,但为了更详细的分析,我在AdventureWorksDW培训基地中模拟了此问题。

有以下形式的查询:

SELECT <some columns>
FROM <some dates table>
CROSS APPLY(

    SELECT
        <some p columns>
    FROM <some table> p
    WHERE p.StartDate <= Dates.d
      AND p.EndDate >= Dates.d
) t
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

从上面给出的执行计划中可以看出,基数估计器估计索引查找操作中的估计行数为 17,884,200(对应于 NL 外部的每行 2,980,700),这与实际数量非常接近.

现在我将修改查询并添加到 CROSS APPLY LEFT OUTER JOIN:

SELECT <some columns t>
FROM <some dates table>
CROSS APPLY(

    SELECT
        <some p columns>
    <some columns f>
    FROM <some table> p
    LEFT JOIN <some table> f ON p.key = f.key
        AND f.date = Dates.d
    WHERE p.StartDate <= Dates.d
      AND p.EndDate …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization cross-apply cardinality-estimates query-performance

10
推荐指数
1
解决办法
390
查看次数

SQL Server 如何估计嵌套循环索引查找的基数

我试图了解 SQL Server 如何估计下面的 Stack Overflow 数据库查询的基数

首先,我创建索引

CREATE INDEX IX_PostId ON dbo.Comments
(
    PostId
)
INCLUDE
(
    [Text]
)
Run Code Online (Sandbox Code Playgroud)

这是查询:

SELECT  u.DisplayName,
        c.PostId,
        c.Text
FROM    Users u
        JOIN Comments c
            ON u.Reputation = c.PostId
WHERE   u.AccountId = 22547
Run Code Online (Sandbox Code Playgroud)

执行计划在这里

首先,SQL Server 扫描用户表上的聚集索引以返回与 AccountId 谓词匹配的用户。我可以看到它使用了这个统计数据:_WA_Sys_0000000E_09DE7BCC

在此输入图像描述

我可以看到该用户没有范围高键,因此 SQL Server 使用 avg_range 行并估计 1

在此输入图像描述

评论索引搜索的搜索谓词是

在此输入图像描述

soScalar Operator([StackOverflow2010].[dbo].[Users].[Reputation] as [u].[Reputation]表示users表中accountId为的用户的信誉值22547

我可以看到总共加载了三个统计数据:

_WA_Sys_0000000E_09DE7BCC- Users.AccountId(用于估计聚集索引查找谓词)

IX_PostId- Comments.PostId(用于估计索引查找谓词)

_WA_Sys_0000000A_09DE7BCC- 用户.声誉 (?)

SQL Server 如何得出索引查找的估计值?它无法在编译时知道 accountId 的信誉,22547因为帐户 …

sql-server execution-plan cardinality-estimates sql-server-2019

3
推荐指数
1
解决办法
298
查看次数