「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節が最適化されないことがわかりました。ただし、実行時間に検出可能な影響はないようです。
dan04

回答:


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))。@JNKが述べたように、1 = 1はパフォーマンスの問題を引き起こすべきではありません(私はそこで彼の答えを+1しました、それは受け入れられるべきです)、Erlandの記事からいくつかの良いヒントを見つけると思います動的SQLを使用する1=1と、パラメーターが渡されない場合にも引き続き使用されますが、渡されない個々のパラメーターに対しては使用されず、単純に使用されます。


2番目の記事を参照しているだけです(現時点では2008 SP1のコードを書いているわけではありません)が、彼コードで1 = 1を使用しています。私は既にsp_executesqlに精通していますが、それだけで1 = 1を使用するプッシュを排除するわけではありません。たぶん私は何かが欠けていますか?
トランジスタ1

2
+1-アーランドは、この種のものに関する頼りになるリソースです。
JNK

2番目のリンクから引用するだけです:「19行
トランジスタ1

2
ごめんなさい。ポイントを間違って入力しました。編集します。Where 1 = 1コンストラクトに問題があることを意味するつもりはありませんでした。読みやすさのために他のヒントを提案し、WHERE(column = valueまたは1 = 1)および(column1 = value1または1 = 1)などのアプローチ。
マイクウォルシュ

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
素晴らしい答え。ところで、MySQLサーバーv5.7.18では、「EXTENDED」は非推奨であり、将来のリリースで削除される予定です。mysql docから: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で削除されました。
13:45の
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.