<>和!=在SQL Server中性能相同的权威来源


74

请在SO上考虑以下答案,以确保向<>操作员提出以下要求:

<>与...相同!=

但随后有一个评论者插话说:

的确,它们在功能上是相同的。但是,SQL优化器如何使用它们却大不相同。= /!=可以简单地评估为true / false,而<>表示引擎必须查看并查看该值是大于还是小于,这意味着更多的性能开销。编写昂贵的查询时要考虑的一件事。

我相信这是错误的,但是为了解决潜在的怀疑者,我想知道是否有人可以提供权威或规范的信息来证明这些运算符不仅在功能上相同,而且在各个方面都相同?

Answers:


144

在解析期间,SQL Server调用sqllang!DecodeCompOp以确定存在的比较运算符的类型:

调用堆栈

在优化程序中的任何事情涉及之前,这种情况就发生了。

来自比较运算符(Transact-SQL)

比较运算符和含义

使用调试器和公共符号*跟踪代码,sqllang!DecodeCompOp在寄存器eax**中返回一个值,如下所示:

╔════╦══════╗
║ Op ║ Code ║
╠════╬══════╣
║ <  ║    1 ║
║ =  ║    2 ║
║ <= ║    3 ║
║ !> ║    3 ║
║ >  ║    4 ║
║ <> ║    5 ║
║ != ║    5 ║
║ >= ║    6 ║
║ !< ║    6 ║
╚════╩══════╝

!=并且<>都返回5,因此在以后的所有操作(包括编译和优化)中都是无法区分的


虽然继发于以上这一点,也可以(例如,使用未记录的跟踪标志8605)看传递给优化的逻辑树,以确认这两个!=<>映射到ScaOp_Comp x_cmpNe(不等于标量操作者比较)。

例如:

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID != 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID <> 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

都产生:

LogOp_Project QCOL:[P] .ProductID
    LogOp_Select
        LogOp_Get TBL:生产。产品(别名TBL:P)
        ScaOp_Comp x_cmpNe
            ScaOp_Identifier QCOL:[P] .ProductID
            ScaOp_Const TI(int,ML = 4)XVAR(int,不拥有,值= 4)
    AncOp_PrjList 

脚注

*我使用WinDbg ; 其他调试器也可用。可通过常规的Microsoft符号服务器获得公共符号。有关更多信息,请参见SQL Server客户咨询团队对使用Minidumps深入研究SQL ServerWinDbg进行SQL Server调试– Klaus Aschenbrenner 的简介

**在32位Intel衍生产品上使用EAX来获取函数的返回值是很常见的。当然,Win32 ABI就是这样做的,而且我很确定它是从旧的MS-DOS时代继承了这种做法的,当时AX被用于相同的目的-MichaelKjörling


58

我在Microsoft的SQL支持部门工作,我问高级升级工程师兼SQL Server性能主题专家Jack Li,“ SQL对待!=与<>有什么不同吗?” 他说:“他们是一样的。”


8

我认为以下证明<>不能进行2次比较。

  1. SQL Standard 92将<>不等于运算符定义为(http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)。从技术上讲,!=是对标准的扩展(即使我不能考虑任何未实现该标准的RDBMS)。
  2. 如果将SQLServer视为<>2个运算符(而不是1个),则><实际上会发生语法错误。

1

这是不正确的,联机丛书(BOL)表示它们在功能上是相同的:

!=(不等于)(Transact-SQL)

如果你看看那里执行计划!=时,谓语下,它的变化 !=<>


2
问题是,尽管您和我都知道“功能相同”包括其实际工作方式及其任何性能特征,但是“功能相同”一词已在引用的注释中被接受,但对性能有所不同。如果要证明这一点超出所有确定的怀疑,那么该怎么办?
ErikE
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.