我在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的任何线索? (请不要使用强制索引。)
答案 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