考虑一下这个关于 SO 的答案,它可以让询问者对<>
运营商感到放心:
<>
是……和……一样!=
。
但随后一位评论者插嘴说:
确实,它们在功能上是相同的。但是,SQL 优化器如何使用它们却大不相同。=/!= 被简单地评估为真/假,而 <> 意味着引擎必须查看该值是大于还是小于,这意味着更多的性能开销。只是在编写可能很昂贵的查询时要考虑的事情。
我相信这是错误的,但为了解决潜在的怀疑论者,我想知道是否有人可以提供权威或规范的来源来证明这些运算符不仅在功能上相同,而且在所有方面都相同?
在解析期间,SQL Server 调用
sqllang!DecodeCompOp
以确定存在的比较运算符的类型:这发生在优化器中的任何内容涉及之前。
使用调试器和公共符号*跟踪代码,
sqllang!DecodeCompOp
在寄存器eax
** 中返回一个值,如下所示:!=
并且<>
都返回 5,因此在所有后续操作(包括编译和优化)中都无法区分。虽然次要于上述点,但也可以(例如,使用未记录的跟踪标志 8605)查看传递给优化器的逻辑树以确认两者
!=
并<>
映射到ScaOp_Comp x_cmpNe
(不等于标量运算符比较)。例如:
两者都产生:
脚注
* 我使用WinDbg;其他调试器可用。公共符号可通过通常的 Microsoft 符号服务器获得。有关详细信息,请参阅SQL Server 客户咨询团队使用 Minidumps 深入了解 SQL Server和使用 WinDbg 进行 SQL Server 调试 - Klaus Aschenbrenner 的介绍。
** 在 32 位 Intel 衍生产品上使用 EAX 来获取函数的返回值是很常见的。当然,Win32 ABI 就是这样做的,我很确定它继承了旧 MS-DOS 时代的这种做法,当时 AX 被用于相同目的 - Michael Kjörling
我在 Microsoft 的 SQL 支持部门工作,我向高级升级工程师和 SQL Server 性能主题专家 Jack Li 提问:“SQL 对待 != 与 <> 有什么不同吗?” 他说:“他们是一样的。”
我认为以下证明
<>
不做 2 比较。<>
不等于运算符定义为 ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt )。从技术上讲,!=
是对标准的扩展(尽管我想不出任何没有实现它的 RDBMS)。<>
其视为 2 个运算符,而不是一个,它会执行相同的操作,><
这实际上是语法错误。这是不正确的,Books Online (BOL) 说它们在功能上是相同的:
!= (不等于) (Transact-SQL)
如果您查看使用的执行计划
!=
,在 Predicate 下,它会更改!=
为<>
.