SQL查询不使用可用索引(SQL Server 2008)

时间:2009-05-14 11:18:35

标签: sql sql-server-2008 indexing

我在SQL Server 2008中有以下表格:

Session
(
sessionid varchar(10)
startdate dateteime
enddate dateteime
--rest of the fields go here
)

我创建了以下两个非聚簇索引:

Inddex1: SessionID,startdate,enddate
Inddex2: startdate,enddate

我有以下查询

select *
from session
where startdate>=@date1 and enddate <=@date2

执行此查询时,不使用这两个idex。查询计划仅显示表扫描。

现在我尝试删除index1并执行相同的SP 还没有使用index2。

有关如何使SP使用index2的任何线索? (请不要使用强制索引。)

5 个答案:

答案 0 :(得分:3)

您是否在SessionID列上有聚簇索引?在这种情况下,您的索引基本相同,因为任何非聚簇索引都将隐式包含聚簇键。

表中有多少行,这些值的基数/唯一性是什么?如果表足够小,表扫描可能比索引查找+ bookmarp查找更有效,以检索剩余的列。

答案 1 :(得分:1)

首先,最好使用一个主键作为唯一的聚簇索引。

我不确定我是否明白这两个综合指数。你对日期的个人指数不是更好吗?

答案 2 :(得分:0)

不会使用复合索引,因为它不能用于对该查询进行操作。您应该在每列上创建一个单独的索引。

答案 3 :(得分:0)

您说查询处理器没有使用您的某个索引,但您没有告诉我们 正在做什么。我假设一个表扫描......?

您的查询没有覆盖索引。因为你正在做“select *”,所以查询处理器知道它最多只能从你的索引中获得一个“书签”(索引会这样做),然后它必须交叉引用该书签。表中的实际数据页。

有了这些知识,查询处理器将查看表中的数据量。如果数据量很小(对于某些小的定义),那么它可能会决定扫描表比通过书签查找跟随的索引更有效。

考虑更改查询和/或索引,以便您只选择索引完全覆盖的字段。然后我希望你看到索引使用情况。但这不一定是正确的事情 - 为很少使用的查询创建一个巨大的索引可能是错误的。

答案 4 :(得分:0)

任何以“startdate”作为第一列的索引都可以帮助您搜索startdate&gt; = @ date1。任何带有“enddate”作为第一列的索引都可以帮助搜索“enddate&lt; = @ date2”。但是没有任何索引可以帮助两者。

假设几乎没有具有相同startdate的enddate,(startdate,enddate)上的索引不比(startdate)上的索引更有用。

因此,表扫描似乎是Sql Server的一个可靠选择。

即使您搜索startdate&gt; = @ date1,执行表扫描仍然有意义。索引扫描会为您提供大量对您必须解决的表的引用,这对于大量数据来说是不值得的。

应该使用索引的一个查询是:

select * from session where startdate = @date1

无论如何,如果你认为你比优化器更了解,你可以强制使用索引,如:

select *
from session with (index indexname)
where startdate>=@date1 and enddate <=@date2