通常“ WHERE 1 = 1”会影响查询性能吗?


19

我最近看到了一个问题“ where 1 = 1 statement”;我在构造动态SQL时经常使用的SQL构造,目的是编写更简洁的代码(从宿主语言的角度来看)。

一般来说,对SQL语句的这种添加是否会对查询性能产生负面影响?我不是在寻找有关特定数据库系统的答案(因为我已经在DB2,SQL Server,MS-Access和mysql中使用了它),除非没有具体说明就不可能回答。


4
我相信任何优化程序都将能够处理这种简单条件,而只是忽略它,因此最终执行计划将根本不包含该条件

我也会这么认为-从逻辑上讲,一般来说查询优化器会忽略它似乎是有道理的。

6
您可以将执行计划与不执行计划进行比较1=1
Luc M

4
@Luc M:我只是为SQLite做的。事实证明,这并不能优化WHILE 1=1条款。但是,它似乎对执行时间没有任何可检测到的影响。
2011年

Answers:


23

据我所知,所有主要的RDBMS都具有持续的评估功能。在任何一个中,这应该立即进行评估。


+1这也是我的猜测,但是我问这个问题的原因是要获得更多细节。我将其保持打开状态更长一点,以查看是否有更多输入。
晶体管1

2
这被忽略。与优化器无关,只是根据每个链接的条件(我的回答也是如此)
gbn

8

从SQL Server的角度来看,如果WHERE 1=1要允许动态传递参数并跳过对参数的求值,则建议您阅读SQL Server MV Erland Sommarskog的几篇文章。他的方法消除了在动态SQL内部执行其他技巧的需要(例如,WHERE Column = Column构造或使用WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)构造)。1 = 1不应引起@JNK提到的性能问题(我在那+1了他的答案,这是应该接受的答案),我想您会在Erland的文章中找到一些不错的技巧动态SQL,您还会看到1=1在没有传递参数的情况下,他仍然使用那个,但对于没有传递的单个参数,他避免使用它们,只是简单地


我只是随便的第二篇文章(因为我没有在时刻2008 SP1编写代码),但我看他在他的代码中使用1 = 1。我已经对sp_executesql熟悉了,但这并不能消除本身使用1 = 1的要求。也许我缺少什么?
transistor1

2
+1-Erland是这类事情的首选资源。
JNK

只是引用第二个链接:“在第19-29行,我编写了基本的SQL字符串。第29行的条件WHERE 1 = 1允许用户调用过程而无需指定任何参数。”
transistor1

2
抱歉。我打错了我的观点。将进行编辑。我并不是要暗示Where 1 = 1构造存在问题,只是建议其他可读性提示,并希望避免采用WHERE(column = value或1 = 1)和(column1 = value1或1 = 1)等方法。
Mike Walsh

6

使用MySQL,您可以检查,运行EXPLAIN EXTENDED和更高版本的SHOW WARNINGS来查看实际查询。tl; dr:已经优化了。

mysql> use test
Database changed
mysql> create table test1(val int);
Query OK, 0 rows affected (0.19 sec)

mysql> explain extended select * from test1 where val > 11 and 1 = 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test1 | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+--------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                    |
+-------+------+--------------------------------------------------------------------------------------------+
| Note  | 1003 | select `test`.`test1`.`val` AS `val` from `test`.`test1` where (`test`.`test1`.`val` > 11) |
+-------+------+--------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

1
好答案。Btw MySQL服务器v5.7.18说'EXTENDED'已过时,将在以后的版本中删除。从mysql文档中:In older MySQL releases, extended information was produced using EXPLAIN EXTENDED. That syntax is still recognized for backward compatibility but extended output is now enabled by default, so the EXTENDED keyword is superfluous and deprecated. Its use results in a warning, and it will be removed from EXPLAIN syntax in a future MySQL release.在MySQL v 8.0中已将其删除。
mikep
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.