2010-11-16 61 views
0

这里是我的查询指数+ SQL Server 2005中

Declare @StartDateTime datetime, @EndDateTime datetime 

Select @StartDateTime = '2010-11-15', @EndDateTime = '2010-11-16' 

Select PracticeCode, AccountNo, ProcCd, Modifier , ChargeDos, Paid as Amt, CreatedDate, 
    case When Paid > 0 then 'P' 
      When Paid = 0 and WrittenOff = DueAmt then 'A' 
      Else 'O' 
    End as Status 
    From Trn_Postings 
    Where CreatedDate >= @StartDateTime and CreatedDate <= @EndDateTime 
      --and ManualOverride in ('S','F','X','G','O') 
      and ManualOverride in ('N','U') 

编辑:创建日期是包含&时间记录的创建

日期我有单独的索引日期时间列在CreatedDate和ManualOverride上。但执行计划显示聚簇索引扫描。该表有近百万条记录,并且在不久的将来可以增长4到5倍。

最令人惊讶的部分是,如果我更改下面的where子句,它使用这两个索引。我只是不知道为什么。

 Where CreatedDate >= @StartDateTime and CreatedDate <= @EndDateTime 
      and ManualOverride in ('S','F','X','G','O') 
      --and ManualOverride in ('N','U') 

如何使SQL中使用索引...

而且如果我使用一个不在条款不会被使用的索引。

+0

因为它的立场,优化*不考虑*索引。它*可能是错误的*在不使用索引为您的第一个案件,但很可能,它不是。你能为这两种情况发布计划吗? – 2010-11-16 07:49:43

+1

使用索引并不总能让您获得更好的性能。一个简单的情况是,强制编译器使用索引的速度会比较慢,通过执行返回** all **行的select。 – 2010-11-16 07:54:19

+0

'通过ManualOverride'从Trn_Postings组中选择ManualOverride,COUNT(*)。如果N和U代表此列中的大部分值,则表示索引对查询不会有用,所以优化器不太可能使用它。 – 2010-11-16 08:02:27

回答

0

我建议创建了CreatedDate和ManualOverride一个综合指数。当使用索引可以满足这两个条件时,这就是优化器似乎在做的事情。

但是一旦知道它必须使用聚集索引来满足查询的一部分,它会显示它忽略了其他索引。它决定COST(使用CreatedDate索引+ CI查找+条件)> COST(扫描CI)。这是错的,但有时会发生。可能会使用两列上的索引(CreatedDate first)。或者你可以尝试使用INDEX query hint强制它的手。它可能仍然会选择忽略提示。

+0

看起来像我必须忍受它: - (...“使用索引”表提示仅在Sql Server 2008中可用...我们仍然使用Sql server 2005 ... – 2010-11-16 09:40:58

+0

@ The King - 根据2005年,你仍然可以提供INDEX提示 - 使用OPTION子句并指定表提示。http://msdn.microsoft.com/en-us/library/ms187373(v=SQL.90).aspx – 2010-11-16 10:37:18

0

鉴于对于找到的每一行匹配where子句,它将不得不返回到聚集索引以获取数据,如果有大量数据被返回,那么只需逐步遍历它可能会更有效并拉出它需要的行。

+0

我的查询返回10M记录中的近10000条记录,仅占记录总数的1%... – 2010-11-16 08:47:19

0

考虑更新的统计数据:

update statistics Trn_Postings with fullscan 
+0

我按照你的建议做了......没有任何变化。 – 2010-11-16 08:47:55