web-dev-qa-db-ja.com

EXISTSはCOUNT(*)> 0よりも効率的ですか?

MySQL 5.1を使用していますが、おおよそ次の形式のクエリがあります。

select count(*) from mytable where a = "foo" and b = "bar";

私のプログラムでは、これがゼロかゼロ以外かをチェックするだけです。これを次のように変換すると:

select exists(select * from mytable where a = "foo" and b = "bar");

mySQLは、最初の検索にヒットしたときに検索を停止するのに十分スマートですか?または、MySQLに通信する他の方法はありますか?私の意図は単にこれに一致するレコードがあるかどうかを確認することであり、正確なカウントは必要ありませんか?

30
Ken

はい、MySQL(私が知る限りすべてのデータベースシステム)は、Exists関数を使用しているときに行が返されると、処理を停止します。

詳細については、MySQLのドキュメントを参照してください。 サブクエリが行を返す場合、EXISTSサブクエリはTRUEです。

29
Thomas

1000個のクエリでテストを実行しました。 SELECT EXISTSSELECT COUNTよりも約25%高速でした。 limit 1SELECT COUNTに追加しても違いはありませんでした。

12
linepogl

最も信頼できる方法はおそらく_LIMIT 1_ですが、それは重要ではありません。

CREATE INDEX mytable_index_a_b ON mytable (a,b)のようなインデックスがある場合、MySQLはインデックスからカウントを返し、行にまったく触れないほど賢いはずです。 LIMIT1の利点はおそらく無視できます。

(a、b)にインデックスがない場合、パフォーマンスはひどいものになります。 LIMIT 1を使用すると、ひどさが大幅に軽減される可能性がありますが、それでもひどい状態になります。

3
tc.

これもアプローチかもしれません。

select 1 from mytable where a = "foo" and b = "bar" limit 1;

これは、where条件を満たすすべてのレコードをトラバースするのではなく、最初の「ヒット」の後に「1」を返します。欠点は、結果が空のレコードセットである可能性があるため、結果を確認する必要があることです。

2
Valyo

これが最適化にどれだけうまく機能するかはわかりませんが、機能的にはexistsと同じように機能するはずです。例外は、一致するものがない場合は行を返さないことです。

SELECT true from mytable where a = "foo" and b = "bar" LIMIT 1;
1
Kevin Peno