建表KeyLevelStat (无主键),2个索引:
CREATE TABLE KeyLevelStat(
[Date] [int] NOT NULL,
[Num] [varchar](8),
[R0] [decimal](6, 3) NULL,
)
GO
CREATE CLUSTERED INDEX IX_KeyLevelStatDate ON KeyLevelStat (Date DESC)
CREATE CLUSTERED INDEX IX_KeyLevelStatNum ON KeyLevelStat (Num DESC)
IX_KeyLevelStatDate clustered Date(-)
IX_KeyLevelStatNum nonclustered Num
然后插入几万条数据进行查询测试,并查看执行计划。
1、where中使用到非聚集索引:
A:select date,num,r0 from KeyLevelStat where num ='600417'
B:select date,num,r0 from KeyLevelStat where num ='600417' or num ='000419'
C:select date,num from KeyLevelStat where num ='600417' or num ='000419'
A与B的执行计划完全一样。
B比C多select了一个R0字段(无索引),导致聚集索引查找。
黄色的“等于”换成“大于”,结果是一样的。
2、where中使用到聚集索引:
A:select date from KeyLevelStat where date >20130912
B:select date,num,r0 from KeyLevelStat where date >20130912
A与B的执行计划完全一样。
3、总结:
1、or其实可以使用到索引的。但大于不行。
2、select的字段也会影响索引使用。(当表同时有聚集索引和非聚集索引时)
-
select包含任意无索引的字段,或者where包含任意无索引的字段,都会扫描聚集索引。
-
若where没用到聚集索引但用到了非聚集索引A,当select包含“A索引的字段 + 聚集索引字段”之外的字段时,会使用聚集索引而使where用到的索引无效
推测原理:
1、无索引的字段需要根据聚集索引来定位,才能select出来。
2、非聚集索引中记录了聚集索引字段的值,故能直接select出来。