2016-06-15 2 views
43

等号を使用したIN演算子と同じ値のSQLエンジンはどのように異なるのですか?実行時間は変化しますか?一つの値だけが存在する場合、SQLエンジンは=INを変更しない使用してOR演算子と単一値等しい値(=)と1つの値を持つINのパフォーマンスの相違

WHERE column_value IN ('All') 

等価性チェックオペレータ

WHERE column_value = 'All' 

第二1を使用して

第一1?

MySQLとPostgreSQLで同じことに違いはありますか?

+19

何百万というルールを学習しようとしないでください。何らかの意味で、常に最高のパフォーマンスを発揮するコードを書くことになります。明らかに正しい結果を生み出す明確でシンプルな*理解可能な*コードを書いてください。パフォーマンス目標を設定します。 *あなたのコードのパフォーマンスを測定*します。それが適切に実行されたら、動いてください。それが上手くいかない場合にのみ、あなたはそれにもっと時間を費やすべきです。そして、その時、あなたの質問のような些細な変化を試してから、もう一度*測定*するのは簡単です。おそらく1つは他のものより速いですが、それは重要な違いを生みますか?* –

+3

合意@Damien_The_Unbeliever。しかし、時には、私はSQLとの単一行または単語を書く間、より心配している –

+1

彼らは同じ99.9999999%です。 'WHERE column_value IN((value = 'All' limit 1)のlist_of_valuesから値を選択してください)'のようなことをしない限り、あなたは大丈夫です。サブクエリは 'in()'節のパフォーマンスに大きな影響を与えます。 – MonkeyZeus

答えて

41

これらの2つの文には違いはなく、INに要素が1つしかない場合、オプティマイザはIN=に変換します。

このような質問がある場合は、両方のステートメントを実行して実行計画を実行し、その違いを確認してください。ここには何も見つかりません。括弧内の一つの値だけがある場合は、この称賛は同等です

は、オンラインで大きな検索した後、私はこれを(私はそれがすべてのDBMSに適用されると仮定)をサポートするためにSQL上のドキュメントを見つけました

"COLUMN_NAME" =「VALUE1

Here is the link to the document。ここで

は、Oracleの両方のクエリの実行計画(ほとんどのDBMSはこれを同じに処理します)です。

EXPLAIN PLAN FOR 
select * from dim_employees t 
where t.identity_number = '123456789' 

Plan hash value: 2312174735 
----------------------------------------------------- 
| Id | Operation     | Name   | 
----------------------------------------------------- 
| 0 | SELECT STATEMENT   |    | 
| 1 | TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES | 
| 2 | INDEX UNIQUE SCAN   | SYS_C0029838 | 
----------------------------------------------------- 

そしてIN()用:

EXPLAIN PLAN FOR 
select * from dim_employees t 
where t.identity_number in('123456789'); 

Plan hash value: 2312174735 
----------------------------------------------------- 
| Id | Operation     | Name   | 
----------------------------------------------------- 
| 0 | SELECT STATEMENT   |    | 
| 1 | TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES | 
| 2 | INDEX UNIQUE SCAN   | SYS_C0029838 | 
----------------------------------------------------- 

あなたが見ることができるように、両者が同一であり、 。これは索引付けされた列にあります。索引付けされていない列についても同様です(全表スキャンのみ)。

+0

このデータベースの公式なリファレンスはありますか?私は検索を試みたが、得られなかった。 –

+0

@SomnathMuluk @SomnathMuluk: – sagi

+0

答えを更新しました: - 私はこれに関するMySQLからのそのような正式な参照はないと思います。テストケースを作成し、その結果が異なる場合はテストケースをテストすることができます。 –

8

単一の値で使用しても差はありません。上記の2つのクエリに対してテーブルスキャン、インデックススキャン、またはインデックスシークをチェックすると、2つのクエリに違いはないことがわかります。

MysqlとPostgresSQLで同じことに違いはありますか?

ありません、それは(Infactは、それは、SQL Server、Oracleのなどを含むデータベースのほとんどのために同じになる)2つのエンジン上の任意の違いを持っ​​ていないでしょう。両方のエンジンが変換されますIN=

4

単一のIN句では、違いはありません。以下は、EMPSテーブルを使用したデモです。

select * from emps where empid in (1) 
select * from emps where empid=1 

実行計画における最初のクエリのための述語:

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0) 

述語の実行計画では2番目のクエリのために:

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0) 

あなたはIN句に複数の値を持っている場合は、結合に変換する方が良い

+3

私はすでに1つの値しか述べていません。 –

+0

@SomnathMuluk:1つの句に対してのみ更新 – TheGameiswar

5

実際に大きな違いはありませんが、のcolumn_valueがインデックスに登録されている場合は、INオペレータがインデックスとして読むことができません。

この問題が発生したので、注意してください。

1

両方で実行計画を実行し、結果を確認する必要があります。

IN()ステートメントの中に1つの値しか置かれていない場合は、通常の=と同じように実行されるので、同じ実行計画が適用されると思います。

このようなクエリでオプティマイザが異なる動作をする理由はありません。

5

ここで行いますあなたのクエリにどのようなバリエーションを自分のために見てみましょうなど、魚にする男性を教える:

mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id = "AMH"\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: sentence 
     type: ref 
possible_keys: sentence_lang_id 
      key: sentence_lang_id 
     key_len: 153 
      ref: const 
     rows: 442 
     Extra: Using where 

をそしてのは、それを他の方法で試してみましょう:あなたはでき

mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id in ("AMH")\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: sentence 
     type: ref 
possible_keys: sentence_lang_id 
      key: sentence_lang_id 
     key_len: 153 
      ref: const 
     rows: 442 
     Extra: Using where 

をmysql EXPLAINリクエストの結果をどのように解釈するかについてhereを読んでください。今のところ、両方のクエリで同じ出力が得られることに注意してください。まったく同じ「実行計画」が生成されます。 type行では、クエリで一意でないインデックス(この場合は外部キー)が使用され、ref行はクエリがこのインデックスに対して定数値を比較することによって実行されることを示しています。

2

異なる視点を追加するだけで、rdbmsシステムの主なポイントの1つは、あなたのためにあなたのクエリを書き換え、そのクエリとそれに類するすべてのものに対して最良の実行計画を選ぶことです。これは、2つのクエリが論理的に同一である限り、与えられたrdbmsに対して常に同じ実行計画を生成する必要があることを意味します。

言い換えれば、多くのクエリは同等です(同じ結果セット)が、データベースそのものを認識できないという制約があるためです。したがって、これらのケースに注意してください(例えば、数値が1〜6のフラグフィールドの場合、db doesn <3in (1,2)と同じです)。しかし、その日の終わりに、andorという文章の読みやすさを考えているのであれば、それを書いたときのパフォーマンスに違いはありません。

関連する問題