现在有下面几种写法,其中IID是主键,主要是判断变量如果为空就查所有,否则查询相应记录。
下面几种写法,最后一种逻辑读非常少,前面几种没有都是clustered index scan,所有逻辑读非常高,
如果一个存储过程有10个输入条件,为了高效,可以用动态SQL 进行判断 或者 一个一个用IF判断,如果用IF判断,条件组合太多了,
这种判断变量是否为空,怎么才能高效 ?
---logical reads 6996
declare @Id varchar(10)='sss'
select * from [dbo].[xxxx] where [IID]=COALESCE(NULLIF(@Id, ''), IID)
---logical reads 6996
declare @Id varchar(10)='sss'
select * from [dbo].[xxxx] where [IID]=ISNULL(@Id, IID)
---logical reads 6996
declare @Id varchar(10)='sss'
select * from [dbo].[xxxx] where @Id IS NULL or [IID]=@Id
---logical reads 7
declare @Id varchar(10)='sss'
if @Id is not null
select * from [dbo].[xxxx] where [IID]=@Id
else
select * from [dbo].[xxxx]
------解决思路----------------------
这种最好使用程序来控制这些,在应用程序中,把 SQL 拼接完成。
如果改不了程序,建议写成 动态 SQL 形式。
------解决思路----------------------
这种情况,多个不定条件兼容空查询,要求高效率,最好的方式是,动态执行,至于在程序或存储过程判断,都可以,关键看你对这个存储过程在你整体程序中的定位
------解决思路----------------------
主要消耗在查询,判断和构造动态语句的构成消耗几乎可以忽略不计的
------解决思路----------------------
这种万能写法,当where中出现多个or,并且表数据量大的情况下,性能极其低下,
因为过多的or会导致查询分析器总是使用聚集索引扫描或全表扫描。