为什么在我的聚集索引上有扫描?
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表的索引扫描?什么会导致聚簇索引上的索引扫描?谢谢
下面是关于SQL Server达到从索引的“引爆点”和交换机寻求索引/表扫描一个很好的博客文章:
http://www.sqlskills.com/BLOGS/KIMBERLY/post/The-Tipping-Point-Query-Answers.aspx
您可能希望看看你的查询过滤的方式,因为临界点往往比人们预期的要少得多。
因为您的WHERE子句不针对索引列。
聚簇索引扫描是SQL Server如何在具有聚簇索引的表上指定全表扫描。这是因为您在SIGN表上没有足够的索引来满足WHERE子句,或者因为它确定SIGN表足够小(或者索引不够选择)以至于表扫描更有效。
仅通过检查查询,您可能必须对DeptID列以及StartTime,EndTime和NEDStatusID的某些组合进行索引以避免表扫描。如果您提出的原因是因为您遇到性能问题,那么您还可以运行“索引调整向导”(现在是SQL2005 +客户端工具中的数据库引擎优化顾问),并提供一些建议以指导创建哪些索引以加快速度打开你的查询。
您对签署表数的限制,如果我读这正确:
WHERE
(A.DeptID = @DeptID OR
S.DeptID = @DeptID
AND
A.[EndTime] > @StartDateTime AND A.[StartTime] < @EndDateTime
AND
A.NEDStatusID = 2
是否有任何的这些限制(如DEPTID,开始时间,结束时间,NEDStatusID)索引?这些字段从您的数据集中进行选择的能力如何?
如果你有10万个。行和NEDStatusID只有10个可能的值,那么对该字段的任何限制总是会产生约。 1 mio。行 - 在这种情况下,对于SQL Server来说,执行全表扫描(聚簇索引扫描)可能会更简单(并且成本更低),特别是如果它还需要检查同一个表上未编入索引的其他WHERE子句,(StartTime,EndTIme等)。
马克
我必须问你对这个查询有什么期望,或者你为什么认为在这种情况下索引扫描是一个问题? – Welbog 2009-07-21 19:47:19
你是否来自另一个DBMS,希望看到像散列连接或群集连接之类的东西?如果是的话,那么你应该知道在SQL Server中,聚集索引只是一个树索引,叶节点就是数据页面。如果您已经知道这一点,那么请忽略此评论。 – kdgregory 2009-07-21 20:38:57