日期:2014-05-17  浏览次数:20574 次

关于MSSQL索引扫描的几个问题,大家帮下。
在网上看了一mssql优化的文章,然后自己也做了下测试。在测试中遇到一些问题希望大牛门解答下。
上测试数据

if OBJECT_ID ('test') is not null
drop table test
go
create table test(id varchar(12),username varchar(10),regtime datetime,tel varchar(10))
create clustered index index_id on test(id)
declare @i int=1
while @i<1000
begin
insert into test
select 'ABCDEF'+right((1000+@i),3),'李_'+RIGHT((1000+@i),3),GETDATE(),'8976'+RIGHT((1000+@i),4)
set @i=@i+1
end

测试语句
SET STATISTICS IO ON
1)select * from test where ID like 'ABCDEF9%'
2)SELECT  * FROM test
3)SELECT * FROM test where LEFT(id,7)='ABCDEF9'
结果


(100 行受影响)
表 'test'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

(999 行受影响)
表 'test'。扫描计数 1,逻辑读取 9 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

(100 行受影响)
表 'test'。扫描计数 1,逻辑读取 9 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)
第二个跟第三条语句都是索引扫描。为什么第三个也是索引页加叶子页全部扫描了。怎么不是块扫描。我在百度找了下‘MSSQL索引扫描的类型’都没有资料。

------解决方案--------------------
引用:
Quote: 引用:

因为列上用了函数就用不到索引,就是全表扫描了
表上面建了聚集索引,所以表扫描就是聚集索引扫描了。

谢谢,那MSSQL索引扫描也像oracle分index unique scan
 index range scan
 index skip scan
 full index scan
 fast full index scan这几种吗?

没有就一个  Clustered Index Scan
------解决方案--------------------
第二个查询,优化器会根据你返回的数据占到整表数据的比例估算是索引查找的开销大还是索引扫描的开销大,你反回了所有数据,索引扫描开销小于索引查找
------解决方案--------------------
sqlserver中没有块扫描的概念吧
------解决方案--------------------
1、SQLServer没有块扫描,只有索引扫描(也就是非聚集索引扫描)、聚集索引扫描、表扫描。
2、1楼的问题:是的
3、第二个语句,由于缺少where条件或者筛选条件,是全表返回,所以除了扫描,没有其他方法,又因为有聚集索引在上面,所以使用了聚集索引扫描。第三个语句,由于在等号左边用了函数,优化器会认为这个是一个别的列,导致即使有索引也无效。也进行扫描
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

因为列上用了函数就用不到索引,就是全表扫描了
表上面建了聚集索引,所以表扫描就是聚集索引扫描了。

谢谢,那MSSQL索引扫描也像oracle分index unique scan
 index range scan
 index skip scan
 full index scan
 fast full index scan这几种吗?

没有就一个  Clustered Index Scan