为什么我的聚集索引上有扫描?

时间:2009-07-21 19:38:12

标签: sql sql-server clustered-index

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 个答案:

答案 0 :(得分:22)

聚簇索引扫描是SQL Server如何在具有聚簇索引的表上指定全表扫描。这是因为您在SIGN表上没有足够的索引来满足WHERE子句,或者因为它确定SIGN表足够小(或者索引不够有选择性),表格扫描会更有效。

只需检查查询,您可能必须索引DeptID列以及StartTime,EndTime和NEDStatusID的某些组合以避免表扫描。如果你问的原因是因为你遇到了性能问题,你也可以运行索引调优向导(现在是SQL2005 +客户端工具中的数据库引擎调优顾问)并让它给出一些关于要创建速度的索引的建议你的查询。

答案 1 :(得分:13)

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

答案 2 :(得分:9)

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

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

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

答案 3 :(得分: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 mio。行和NEDStatusID只有10个可能的值,那么对该字段的任何限制总是会产生约。 1 mio。行 - 在这种情况下,SQL Server执行全表扫描(聚簇索引扫描)可能更容易(且成本更低),特别是如果它还需要在同一个表上检查未编制索引的其他WHERE子句,(StartTime,EndTIme等)。

马克