SQL Server 2005 强行扫描索引利和弊分析(1)
昨晚在研究SQL Server 2005 强行扫描索引时,在数据量小时,IO逻辑读比较稳定,一旦数据量达到了一定程度以后,IO逻辑读数据会变化很大
测试环境:建立数据表:
CREATE TABLE [dbo].[[zping.com]]](
[id] [varchar](32) NOT NULL,
[workflowid] [varchar](32) NULL,
[stepid] [varchar](32) NULL,
[logtype] [varchar](32) NULL,
[operator] [varchar](32) NULL,
[isfinished] [int] NULL,
[remark] [varchar](32) null
)
[id] [varchar](32) NOT NULL,
[workflowid] [varchar](32) NULL,
[stepid] [varchar](32) NULL,
[logtype] [varchar](32) NULL,
[operator] [varchar](32) NULL,
[isfinished] [int] NULL,
[remark] [varchar](32) null
)
在表中插入70万条数据,我的测试机上目前已经有70万条数据。建立表索引:
CREATE INDEX [idx_operator] ON [dbo].[[zping.com]]]
(
[operator] ASC
)
(
[operator] ASC
)
运行以下语句,查看数据
select count(*),operator from [dbo].[[zping.com]]]
group by operator order by 1 desc
group by operator order by 1 desc
数据目前有237条记录
1,大体分布: 大部分是operato中有1-4000条数据。
2,有两个operator比较多:3万多行,一个有4万行
3,其他大体在1-2万条。
测试operator:一个432行, 一个42020行。
测试oprator为432行时,逻辑IO的是一直的,没有变化。因为他是一直在扫描索引。
测试oprator为42020行时。
执行语句:
select * from [dbo].[[zping.com]]]
where operator='402882ed0eb78aae010ec124f7fe5c87'
where operator='402882ed0eb78aae010ec124f7fe5c87'
反馈结果:
(42020 行受影响)
表 '[zping.com]'。扫描计数 3,逻辑读取 19497 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 3,逻辑读取 19497 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
这时查看执行计划发现数据库是执行表扫描
我们看看强行扫描索引,
执行语句:
select * from [dbo].[[zping.com]]] with(index=idx_operator)
where operator='402882ed0eb78aae010ec124f7fe5c87'
where operator='402882ed0eb78aae010ec124f7fe5c87'
反馈结果:
42020 行受影响)
表 '[zping.com]'。扫描计数 3,逻辑读取 42385 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 3,逻辑读取 42385 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
这里发现数据逻辑读取在42385次,是全表扫描的2倍多,为何多出这么多,我们先看看执行计划:
和索引扫描的差别就是多了个“sort ”排序,就多出这么多?
是因为多了“sort ”排序造成的吗?
我们来做个测试:
select * from [dbo].[[zping.com]]]
where operator='402882ed0e649cdf010e64ce23e503e1' order by id
where operator='402882ed0e649cdf010e64ce23e503e1' order by id
增加一个id排序功能和不加id排序功能进行对比。
发现逻辑读取是一样的,都是 72 次,排序的比没排序多出一个”sort“排序。
说明:多出这么多说明不是“sort”排序造成的。
那为何多出这么多IO逻辑读取?