3

現在、MySQL 5.6.10 を使用しています。

私の実際のクエリはもっと​​複雑ですが、問題を再現する簡単な方法を次に示します。以下のクエリが役に立たないことはわかっています (select id from x where id in (select id from x...)) が、私の主張を証明しています。

このテーブルを作成しました:

CREATE  TABLE test (
  id INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (id));

次に、このコマンドを 5 回実行しました。テーブルに 50 行が作成されました。

INSERT INTO test (id) VALUES(null),(null),(null),(null),(null),(null),(null),(null),(null),(null);

そして、この説明を実行しました:

EXPLAIN SELECT id FROM test WHERE 
       id in (SELECT id FROM test WHERE id < 5);

そして、これを得ました: 4列

これは私にとって完全に理にかなっています。しかし、次のように、別の IN を使用して WHERE 句に OR を追加すると、次のようになります。

EXPLAIN SELECT id FROM test WHERE 
       id IN (SELECT id FROM test WHERE id < 5)
    OR id IN (SELECT id FROM test WHERE id > 45);

突然、MySQL は 50 行すべてを見ています。 50行

SELECT id FROM test WHERE id < 5 OR id > 45クエリが、または UNION などとして書き直される可能性があることはわかっていますが、それは重要ではありません。問題は、MySQL が調べている行が多すぎるということです。

最初のクエリで FLUSH STATUS / SHOW STATUS LIKE "Handler%" を実行すると、次のようになります。

Handler_read_key 5
Handler_external_lock 4
Handler_read_next 4
Handler_read_first 1

しかし、2 番目のクエリに対してこれを行うと、次のようになります。

Handler_read_key 99
Handler_write 9
Handler_external_lock 6
Handler_read_next 59
Handler_read_first 2

大きな違いはなぜですか?それがオプティマイザーなのだろうか、もしそうなら、この「最適化」を防ぐクエリに含めることができるオプションはありますか? これは、私が開発しているクエリにとって実際的な意味を持ちます。数百行だけを調べる代わりに、MySQL は 120,000 行を調べています。

4

1 に答える 1