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に通信する他の方法はありますか?私の意図は単にこれに一致するレコードがあるかどうかを確認することであり、正確なカウントは必要ありませんか?
はい、MySQL(私が知る限りすべてのデータベースシステム)は、Exists関数を使用しているときに行が返されると、処理を停止します。
詳細については、MySQLのドキュメントを参照してください。 サブクエリが行を返す場合、EXISTSサブクエリはTRUEです。
1000個のクエリでテストを実行しました。 SELECT EXISTS
はSELECT COUNT
よりも約25%高速でした。 limit 1
をSELECT COUNT
に追加しても違いはありませんでした。
最も信頼できる方法はおそらく_LIMIT 1
_ですが、それは重要ではありません。
CREATE INDEX mytable_index_a_b ON mytable (a,b)
のようなインデックスがある場合、MySQLはインデックスからカウントを返し、行にまったく触れないほど賢いはずです。 LIMIT1の利点はおそらく無視できます。
(a、b)にインデックスがない場合、パフォーマンスはひどいものになります。 LIMIT 1を使用すると、ひどさが大幅に軽減される可能性がありますが、それでもひどい状態になります。
これもアプローチかもしれません。
select 1 from mytable where a = "foo" and b = "bar" limit 1;
これは、where条件を満たすすべてのレコードをトラバースするのではなく、最初の「ヒット」の後に「1」を返します。欠点は、結果が空のレコードセットである可能性があるため、結果を確認する必要があることです。
これが最適化にどれだけうまく機能するかはわかりませんが、機能的にはexists
と同じように機能するはずです。例外は、一致するものがない場合は行を返さないことです。
SELECT true from mytable where a = "foo" and b = "bar" LIMIT 1;