18

SQL 2000
NED 表有一个外键到 SIGN 表 NED.RowID 到 SIGN.RowID
SIGN 表有一个外键到 NED 表 SIGN.SignID 到 NED.SignID
RowID 和 SignID 是集群主键,它们是 GUID (不是我的选择)
WHERE 子句是:

FROM
    [SIGN] A   
    INNER JOIN NED N ON A.SIGNID = N.SIGNID  
    INNER JOIN Wizard S ON A.WizardID = S.WizardID   
    INNER JOIN [Level] SL ON N.LevelID = SL.LevelID  
    LEFT JOIN Driver DSL ON SL.LevelID = DSL.LevelID  
        AND DSL.fsDeptID = @fsDeptID  
    INNER JOIN [Character] ET ON S.CharacterID = ET.CharacterID  
    INNER JOIN Town DS ON A.TownID = DS.TownID   
WHERE  
    (A.DeptID = @DeptID OR   
    S.DeptID = @DeptID  
    AND   
    A.[EndTime] > @StartDateTime AND A.[StartTime] < @EndDateTime  
    AND   
    A.NEDStatusID = 2    

为什么这个查询的 SIGN 表上有一个 INDEX SCAN?什么会导致对聚集索引进行索引扫描?谢谢

4

4 回答 4

22

聚集索引扫描是 SQL Server 指定对具有聚集索引的表进行全表扫描的方式。这是因为您在 SIGN 表上没有足够的索引来满足 WHERE 子句,或者因为它决定 SIGN 表足够小(或索引不够选择性)以使表扫描更有效。

仅通过检查查询,您可能必须索引 DeptID 列以及 StartTime、EndTime 和 NEDStatusID 的某种组合以避免表扫描。如果您询问的原因是因为您遇到了性能问题,您还可以运行索引优化向导(现在是 SQL2005+ 客户端工具中的数据库引擎优化顾问)并让它就创建哪些索引以加快速度提供一些建议提出您的查询。

于 2009-07-21T19:51:08.930 回答
14

因为您的 WHERE 子句不针对索引列。

于 2009-07-21T19:46:24.633 回答
9

这是一篇关于 SQL Server 何时到达“临界点”并从索引搜索切换到索引/表扫描的好博文:

http://www.sqlskills.com/BLOGS/KIMBERLY/post/The-Tipping-Point-Query-Answers.aspx

您可能想查看查询的过滤方式,因为临界点通常比人们预期的要少得多。

于 2009-07-24T04:23:04.310 回答
2

如果我没看错的话,你对 SIGN A 表有几个限制:

WHERE  
        (A.DeptID = @DeptID OR   
        S.DeptID = @DeptID  
        AND   
        A.[EndTime] > @StartDateTime AND A.[StartTime] < @EndDateTime  
        AND   
        A.NEDStatusID = 2

这些限制(如 DeptID、StartTime、EndTime、NEDStatusID)是否已编入索引?这些领域从您的数据集中选择的情况如何?

如果你有 10 米奥。rows 和 NEDStatusID 只有 10 个可能的值,那么对该字段的任何限制都会产生大约。1米奥。行 - 在这种情况下,SQL Server 执行全表扫描(聚集索引扫描)可能更容易(成本更低),特别是如果它还需要检查同一张表上未编入索引的其他 WHERE 子句, 无论是(开始时间,结束时间等)。

马克

于 2009-07-21T20:25:24.710 回答