SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法
出生缺陷,分手擂台是真的吗,祥仔j8av
set @sql = 'select * from comment with(nolock) where 1=1
and (@projectids is null or projectid = @projectids)
and (@scores is null or score =@scores)'
印象中记得,以前在做oracle开发时,这种写法是会导致全表扫描的,用不上索引,不知道sql server里是否也是一样呢,于是做一个简单的测试
1、建立测试用的表结构和索引:
create table aaa(id int identity, name varchar(12), age int)
go
create index idx_age on aaa (age)
go
2、插入1万条测试数据:
declare @i int;
set @i=0;
while @i<10000
begin
insert into aaa (name, age)values(cast(@i as varchar), @i)
set @i=@i+1;
end
go
3、先开启执行计划显示:
在sql server management studio的查询窗口里,右击窗口任意位置,选择“包含实际的执行计划”:
4、开始测试,用下面的sql进行测试:
declare @i int;
set @i=100
select * from aaa where (@i is null or age = @i)
select * from aaa where (age = @i or @i is null)
select * from aaa where age=isnull(@i, age)
select * from aaa where age = @i
测试结果如下:
可以看到,即使@i有值,不管@i is null是放在前面还是放在后面,都无法用到age的索引,另外age=isnull(@i,age)也用不上索引
最终结论,sql server跟oracle一样,如果条件里加了 变量 is null,都会导致全表扫描。
建议sql改成:
declare @i int;
set @i=100
declare @sql nvarchar(max)
set @sql = 'select * from aaa'
if @i is not null
set @sql = @sql + ' where age = @i'
exec sp_executesql @sql, n'@i int', @i
当然,如果只有一个条件,可以设计成2条sql,比如:
declare @i int;
set @i=100
if @i is not null
select * from aaa where age = @i
else
select * from aaa
但是,如果条件多了,sql数目也变得更多,所以建议用exec的方案
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!!
点击进行留言回复
相关文章:
-
-
-
sql某个日期是当年的第几周
/* *周一作为一周的开始 *当年的1月1号所在的周算作第一周 */ CREATE function GetWeekIndexFirstDate ( @...
[阅读全文]
-
-
数据库SQL---范式
1、数据冗余导致的问题:冗余存储、更新异常、插入异常、删除异常。 2、函数依赖:一种完整性约束。 在关系模式r(R)中,α属于R,β属于R。 1)α函数...
[阅读全文]
-
-
数据库SQL---查询
1、查询所有列 select *from emp;--*表示所有的,from emp表示从emp表中查询。 2、查询指定列 select empno,e...
[阅读全文]
-
-
-
-
网友评论