Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql OR运算符的性能与合并_Sql_Sql Server_Sql Tuning - Fatal编程技术网

Sql OR运算符的性能与合并

Sql OR运算符的性能与合并,sql,sql-server,sql-tuning,Sql,Sql Server,Sql Tuning,比较这些陈述 SELECT * FROM Table WHERE (field IS NULL OR field = 'empty_value') vs 就性能而言,哪一个更好?有什么区别吗 我已经知道第一个需要稍微复杂一些的过滤操作,而第二个需要在过滤之前进行+1标量计算。在单个表中执行此操作对性能的影响很小,但是当查询很复杂时会发生什么呢?在这种情况下,当有多个字段时?我应该选择一个而不是另一个吗 PS:我使用'empty\u value'作为一种通用方式来描述缺少特定值(=NULL)

比较这些陈述

SELECT * FROM Table
WHERE
  (field IS NULL OR field = 'empty_value')
vs

就性能而言,哪一个更好?有什么区别吗

我已经知道第一个需要稍微复杂一些的过滤操作,而第二个需要在过滤之前进行+1标量计算。在单个表中执行此操作对性能的影响很小,但是当查询很复杂时会发生什么呢?在这种情况下,当有多个字段时?我应该选择一个而不是另一个吗

PS:我使用
'empty\u value'
作为一种通用方式来描述缺少特定值(
=NULL
)和特定值(
='empty\u value'
)对查询具有相同含义的情况。更改表设计中的任何内容或其存储值的方式都不是选项

PS2:我正在使用SQL Server,但我想得到一个关于这个问题的更一般的答案。但是,如果答案取决于实现,我会坚持使用SQL Server。

COALESCE()排除了索引的使用(即,它不是可搜索的)。
提供了使用索引的机会。但是,如果查询中存在其他条件,这可能会变得复杂


在一种情况下对解决方案进行基准测试不会给出明确的答案。如果索引不是一个问题,我不会期望性能有太大差异。然而,即使在这种情况下,
的短路也会给它带来优势。

不是这样的答案,但这对于评论来说是太多的信息,并且与问题相关

在这种情况下,我想到了第三种选择:

SELECT *
FROM Table
WHERE field IS NULL 
UNION ALL
SELECT *
FROM Table
WHERE field = 'empty_value'

这是可搜索的,但将查询分为两部分,因此由您来测试所有备选方案。

使用explain查找两个查询的执行计划并进行比较。查找执行计划,查找执行的读取统计信息,并按问题中所述运行20次和基准运行时间,我已经知道每个更改将在结果查询中产生的差异。但这并不是答案:“两个都做,基准测试,选择一个”。我正在寻找一种更具理论性的方法来决定在编写SQL时哪种方法更好。这里没有正确或错误的答案。这可能是因为比较单个列时,差异很小或没有差异。这可能是因为列没有索引,表中的行计数很小。但是在一张大桌子上有一个不同的答案。然后,如果您像在搜索查询中一样开始比较多个列,它会再次发生变化。没有人回答“模式X是最好的”。第二个选择是无可争议的,一般来说,我会避开它,但“基准”是最普遍意义上的正确答案。任何想让你相信无论数据库系统、索引结构、统计数据、版本、优化器标志等如何,其中一个总是会更好的人,时代都在向你推销一些东西。(所有这一切,特别是对于SQL Server,
A为NULL或A=value
往往比
COALESCE(A,value)=value
更好,因为前者可以通过搜索得到满足,而后者会导致扫描。)请小心使用术语“短路”。T-SQL显式不短路;从逻辑上讲,始终对表达式的所有部分求值,即使优化器有时会意外地删除某些部分。这个问题使用常量,然后这种消去确实发生了,但这仅仅是因为我们在处理常量。(我不认为我在告诉你什么新鲜事,但无辜的读者应该受到保护。)@Jeroenmoster,我不同意你的看法。在编程风格的意义上,如果短路是可行的,您可以在关于性能的讨论中假定它(即使您使用的特定语言出于任何原因没有使用它)。我不认为这是一个危险的假设。@DiegoQueiroz:当您认为
其中列0和1/Column=3
不会给出零除错误时,这非常重要,因为在t-SQL中,它可能会给出零除错误。(或者,这是一件可怕的事情,可能不是,这取决于执行计划和实际遇到的行。)你最好使用T-SQL不会短路的心智模型。不是真的。我已经承认,我知道优化器有时会删除表达式的某些部分,即使该语言在逻辑上没有短路。你的玩具例子显然是合格的。不过,在这一点上,如果我不想被困在构建一个实际的反例(可能需要设置一个大表)的过程中,我觉得我最好把它作为一个单独的问题。当然,我已经知道它们的存在,因为我在日常工作中遇到了它们,但那已经有一段时间了。我的观点是,这条线索都是关于性能的。如果我们开始谈论其他事情,比如某个特定构造可能导致的错误,那么我们需要开始一个新的线程。从这个角度来看,@GordonLinoff的评论是完美的:你可能会从短路中获益。伟大到足以引证,他做到了。
SELECT *
FROM Table
WHERE field IS NULL 
UNION ALL
SELECT *
FROM Table
WHERE field = 'empty_value'