Sql server 通过将值转换为带isnull的常量与null进行比较
我们的一位程序员倾向于在MS SQL中使用isnull来与null进行比较。 这不是在ColumnName为Null的地方写Sql server 通过将值转换为带isnull的常量与null进行比较,sql-server,null,isnull,Sql Server,Null,Isnull,我们的一位程序员倾向于在MS SQL中使用isnull来与null进行比较。 这不是在ColumnName为Null的地方写,而是在ColumnName为Null的地方写(ColumnName,0)=0 我认为优化器无论如何都会将后者转换为前者,但如果它没有转换,有没有办法证明后者的效率较低,因为它 1.与null相比, 2.转换为整数, 3.比较2个整数 而不仅仅是与null进行比较 这两种方法对我来说都非常快,可以使用执行计划(而且我认为,优化器发挥了作用)。有没有办法向他证明,只与不带Is
,而是在ColumnName为Null的地方写(ColumnName,0)=0
我认为优化器无论如何都会将后者转换为前者,但如果它没有转换,有没有办法证明后者的效率较低,因为它
1.与null相比,
2.转换为整数,
3.比较2个整数
而不仅仅是与null进行比较
这两种方法对我来说都非常快,可以使用执行计划(而且我认为,优化器发挥了作用)。有没有办法向他证明,只与不带IsNull的Null进行比较更有效(除非不是这样)。如果在where子句中使用IsNull并将其与0进行比较,那么IsNull的使用将取代Null值
例如:
SELECT Description, DiscountPct, MinQty, ISNULL(MaxQty, 0.00) AS 'Max Quantity'
FROM Sales.SpecialOffer;
另一个明显的问题是ISNULL
排除了索引的使用
运行此安装程序:
create table T1 (
ID int not null primary key,
Column1 int null
)
go
create index IX_T1 on T1(Column1)
go
declare @i int
set @i = 10000
while @i > 0
begin
insert into T1 (ID,Column1) values (@i,CASE WHEN @i%1000=0 THEN NULL ELSE @i%1000 END)
set @i = @i - 1
end
go
然后打开执行计划并运行以下操作:
select * from T1 where Column1 is null
select * from T1 where ISNULL(Column1,0)=0
第一种方法使用索引搜索(使用IX_T1
),效率很高。第二种方法对聚集索引进行索引扫描——它必须查看表中的每一行
在我的机器上,第二次查询花费了90%的时间,第一次是10%。显而易见的是,如果0
是该列的有效值,它们会做不同的事情。但是,在一天结束的时候,如果你在这个领域遇到了性能瓶颈,恭喜你——如果不是,我也不会担心。对不起。假设0
对该列无效,且所有值都大于零,但NULL
有效。我的意思是,我们看到的情况是,在这种特定情况下,两个条件都相等。但这就是为什么“我认为优化器无论如何都会将后者转换为前者”是不正确的原因。它速度较慢,可读性较差。在这两种情况中,我最讨厌的部分是可读性差。是的,这就是重点。再加上额外的代码,阅读变得更加复杂。虽然如果他们是同样有效的,都返回正确的结果,这家伙看起来相当任性。他实际上是我的老板:-)此外,你有可搜索的东西,它根本不是可搜索的,在wiki中,你的例子显示为不可搜索。所以你知道,你不能利用indexes@LievenKeersmaekers-我相当确定它不是SARGable,但我对搜索中找到的页面不满意(它们都有点模糊,或者在同一页面上提到了ISNULL
和SARGable,但方式不相关),这将是一个很好的例子,谢谢因为我只管理了50%-50%的非索引字段的表扫描。@Damien_The_unsiever-是否存在在where子句中使用函数是可搜索的情况?