使用 TOP 条件估计的行数有误

Tia*_*ago 3 sql-server index-statistics

我想这是一个非常基本的问题,但我无法理解它。我对一列有完美的统计数据,但是在使用 TOP 条件时,估计的行数总是非常接近于使用的数字对于 TOP 运营商给我一个完全错误的数字。知道应用程序表上的InterviewerID 的统计信息确切地知道ID 12868 行有超过3K 行,对此有什么简单的解释吗?为什么告诉我 13.83?

使用的版本:Microsoft SQL Server 2008 R2 (SP3) - 10.50.6000.34 (X64)

谢谢你们!

我怎么称呼SP?EXEC agy.sp_searchTest3 @interviewerId = 12868,@searchTerm = 'aar'

错误的行数

导致问题的查询:

ALTER PROCEDURE [agy].[sp_searchTest3] (
    @interviewerId INT
    ,@searchTerm VARCHAR(50) = NULL
    ,@searchApplicationId INT = NULL
    )
AS
BEGIN
    IF @searchApplicationId IS NOT NULL
        SELECT TOP 10 u.userId
            ,u.firstName + ' ' + u.lastName AS 'fullname'
            ,app.applicationId
            ,u.loginId AS email
            ,adi.URI AS imageurl
        FROM [app].[application] AS app
        INNER JOIN [app].[applicant] AS a ON a.applicantId = app.applicantId
        INNER JOIN [usr].[user] AS u ON u.userId = a.userId
        LEFT JOIN upl.applicationDocuments AS ud ON ud.applicationId = app.applicationId
            AND ud.documentTypeId = 5 -- (Portrait pic)
            AND ud.documentStateId NOT IN (
                3
                ,5
                ) -- (Rejected, Deleted)
        LEFT JOIN upl.applicationDocumentImages AS adi ON adi.documentId = ud.documentId
        WHERE app.interviewerId = @interviewerId
            AND u.isActive = 1
            AND app.applicationId = @searchApplicationId


    IF @searchTerm IS NOT NULL
        SELECT 
        TOP 15 -- everytime I change the top value the estimated number of rows change as well
        u.userId
            ,u.firstName + ' ' + u.lastName AS 'fullname'
            ,app.applicationId
            ,u.loginId AS email
            ,adi.URI AS imageurl
        FROM [app].[application] AS app
        INNER JOIN [app].[applicant] AS a ON a.applicantId = app.applicantId
        INNER JOIN [usr].[user] AS u ON u.userId = a.userId
        LEFT JOIN upl.applicationDocuments AS ud ON ud.applicationId = app.applicationId
            AND ud.documentTypeId = 5 -- (Portrait pic)
            AND ud.documentStateId NOT IN (
                3
                ,5
                ) -- (Rejected, Deleted)
        LEFT JOIN upl.applicationDocumentImages AS adi ON adi.documentId = ud.documentId
        WHERE app.interviewerId = @interviewerId
            AND u.isActive = 1
            AND (
                (u.firstName LIKE @searchTerm)
                OR (u.lastName LIKE @searchTerm)
                OR (u.loginId LIKE @searchTerm)
                )
END
Run Code Online (Sandbox Code Playgroud)

Rob*_*ley 5

13.83是它认为满足您要求的 15 行所需的行数。它猜测在那之后它可以停止。

Paul White 在他的文章Inside Optimizer Row Goals in Depth 中对此进行了更多的讨论。

由于他在此站点上花费了大量时间,您可能会看到一个广泛的答案,其中详细介绍了为什么是 13.83 而不是 13.84。;)

我建议您阅读以下博客