将可为空的列包装在 ISNULL 中是否会导致表扫描?
Visual Studio 2010 数据库项目的代码分析规则 SR0007 指出:
您应该通过将可以包含 NULL 值的每一列包装在 ISNULL 函数中来明确指示如何处理比较表达式中的 NULL 值。
但是,在以下情况下会违反代码分析规则 SR0006:
作为比较的一部分,表达式包含列引用...如果您的代码比较包含列引用的表达式,则可能会导致表扫描。
这是否也适用于 ISNULL,或者 ISNULL 永远不会导致表扫描?
Code analysis rule SR0007 for Visual Studio 2010 database projects states that:
You should explicitly indicate how to handle NULL values in comparison expressions by wrapping each column that can contain a NULL value in an ISNULL function.
However code analysis rule SR0006 is violated when:
As part of a comparison, an expression contains a column reference ... Your code could cause a table scan if it compares an expression that contains a column reference.
Does this also apply to ISNULL, or does ISNULL never result in a table scan?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,它会导致表扫描。 (尽管如果该列实际上不可为空,则似乎会得到优化)
SR0007 规则是非常糟糕的一揽子建议,因为它使谓词不可控制,并且意味着列上的任何索引都将毫无用处。即使列上没有索引,它仍然可能使基数估计不准确,影响计划的其他部分。
它在 Microsoft.Performance 类别中的分类非常有趣,因为它似乎是由不了解查询性能的人编写的。
它声称其理由是
虽然表达式本身的计算结果为
unknown
,但一旦您了解任何=
、<>
、>
、<
等与NULL
的比较评估为Unknown
并且WHERE
子句仅返回表达式计算结果为的行真
。它们的意思可能是
ANSI_NULLS
关闭,但示例他们在WHERE ISNULL([c2],0) > 的文档中给出了2;
与WHERE [c2] > 2;
无论如何都不会受到此设置的影响。这个设置显示扫描与查找或以下的执行计划
Yes it causes table scans. (though seems to get optimised out if the column isn't actually nullable)
The SR0007 rule is extremely poor blanket advice as it renders the predicate unsargable and means any indexes on the column will be useless. Even if there is no index on the column it might still make cardinality estimates inaccurate affecting other parts of the plan.
The categorization of it in the
Microsoft.Performance
category is quite amusing as it seems to have been written by someone with no understanding of query performance.It claims the rationale is
Whilst the expression itself does evaluate to
unknown
your code returns a completely deterministic result once you understand that any=
,<>
,>
,<
etc comparison withNULL
evaluate asUnknown
and that theWHERE
clause only returns rows where the expression evaluates totrue
.It is possible that they mean if
ANSI_NULLS
is off but the example they give in the documentation ofWHERE ISNULL([c2],0) > 2;
vsWHERE [c2] > 2;
would not be affected by this setting anyway. This settingExecution plans showing scans vs seek or below