我觉得是正常的 因为要先得到视图结果,所以条件where a = '1'要先执行,就是进行表扫描.再在结果集中执行条件:b = 'xxx' and c = 'yyy' Filter
你可以使用索引提示功能强制SQL Server按照你的方法访问数据库 可以使用 select '1',b,c,d,e from T1 union select a,b,c,d,e from T2(index='indexnanme') where a = '1'你在试验一下
要不你用fun:create function 名 (@b varchar(100),@c varchar(100)) returns table as return( select '1',b,c,d,e from T1 where b=@b and c=@c union all select a,b,c,d,e from T2 where b=@b and c=@c and a='1') go--调用:select * from 名('xx','yy')
下午去做过测试:结果如下: t1表需要建立字段b,c的组合索引 t2表需要建立字段a,b,c的组合索引 创建后,用查询分析器执行: select * from V where b='xxx' and c='yyy'可以看到分析结果: T1上用了(b,c)索引,筛选条件:b='xxx' and c='yyy' T2上用了(a,b,c)索引,筛选条件:a = '1' and b='xxx' and c='yyy' 而且不会在T2上执行Table scan而且,如果创建的索引为非聚集索引的话,数据会有两次动作. 如果创建为聚集索引,则一次扫描取数.
to zjcxc(邹建): 在我开发的机器上也是好的,可在真实的运行环境就不行了。 区别主要是我的机器是单CPU,;运行环境4CPU,查询分析器生成的查询计划有个并行处理。 开发环境数据量小,而运行环境数据量是很大的T1有9000多万条记录,T2有1000千多万条记录。 如果我不用视图直接用SQL查询,像这样: select '1',b,c,d,e from T1 where b='xxx' and c='yyy' union all select a,b,c,d,e from T2 where a = '1'and b='xxx' and c='yyy' 那么查询分析器显示用到了T2(a,b,c)的索引。 我就不知道,MSSQL SERVER对视图是怎么做优化的。
union all
select a,b,c,d,e from T2 where a = '1'
我把Union改为Union all,问题依然没有解决
我又在T2上建了(a,b,c)的索引,可查询计划依然现实对T2执行了Table scanTo:CrazyFor(蚂蚁) ( )
我说得没有道理指的是因该先使用T2(b,c)的索引,再用a='1' Filter还得请教各位!
因为要先得到视图结果,所以条件where a = '1'要先执行,就是进行表扫描.再在结果集中执行条件:b = 'xxx' and c = 'yyy' Filter
可以使用
select '1',b,c,d,e from T1
union
select a,b,c,d,e from T2(index='indexnanme') where a = '1'你在试验一下
returns table as
return( select '1',b,c,d,e from T1 where b=@b and c=@c union all select a,b,c,d,e from T2 where b=@b and c=@c and a='1')
go--调用:select * from 名('xx','yy')
后来由于某种原因我将T2表重建(具体的说是用sp_rename过程将T2表重新命名了,又建了一个T2的表),索引也按照原来的建的,可查询速度就不行了。
我不知道以前的那位同事是怎么做的,可惜现在他不在了。还有一个问题我不明白,既然我建了T2(a,b,c)索引那么,分析试图中where a='1' 时也应该用这个索引啊?
这样不行的,因为还可能有其他查询参数,我只是举个例子而已。
t1表需要建立字段b,c的组合索引
t2表需要建立字段a,b,c的组合索引
创建后,用查询分析器执行:
select * from V where b='xxx' and c='yyy'可以看到分析结果:
T1上用了(b,c)索引,筛选条件:b='xxx' and c='yyy'
T2上用了(a,b,c)索引,筛选条件:a = '1' and b='xxx' and c='yyy'
而且不会在T2上执行Table scan而且,如果创建的索引为非聚集索引的话,数据会有两次动作.
如果创建为聚集索引,则一次扫描取数.
我的测试环境:sql 2000+sp3,win2000+sp4
在我开发的机器上也是好的,可在真实的运行环境就不行了。
区别主要是我的机器是单CPU,;运行环境4CPU,查询分析器生成的查询计划有个并行处理。
开发环境数据量小,而运行环境数据量是很大的T1有9000多万条记录,T2有1000千多万条记录。
如果我不用视图直接用SQL查询,像这样:
select '1',b,c,d,e from T1 where b='xxx' and c='yyy'
union all
select a,b,c,d,e from T2 where a = '1'and b='xxx' and c='yyy'
那么查询分析器显示用到了T2(a,b,c)的索引。
我就不知道,MSSQL SERVER对视图是怎么做优化的。