回答:
あなたも試すことができますEXISTS
:
SELECT EXISTS(SELECT * FROM table1 WHERE ...)
伝統的に、EXISTSサブクエリはSELECT *で始まりますが、SELECT 5またはSELECT column1などで始まる可能性があります。MySQLはそのようなサブクエリのSELECTリストを無視するため、違いはありません。
SELECT 1 FROM table1 WHERE col = $var LIMIT 1
はあなたのクエリよりも高速です。では、クエリの利点は何ですか?
私は最近この問題についていくつかの研究をしました。フィールドがTEXTフィールドであり、一意でないフィールドである場合、それを実装する方法は異なる必要があります。
TEXTフィールドを使用していくつかのテストを行いました。100万のエントリを持つテーブルがあることを考慮してください。37のエントリは「何か」に等しいです。
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
と
mysql_num_rows()
:0.039061069488525s。(もっと早く)SELECT count(*) as count FROM test WHERE text LIKE '%something%
:16.028197050095s。SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%')
:0.87045907974243s。SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%'
LIMIT 1)
:0.044898986816406s。しかし今、BIGINT PKフィールドでは、1つのエントリのみが「321321」に等しくなります。
SELECT * FROM test2 WHERE id ='321321' LIMIT 1
で
mysql_num_rows()
:0.0089840888977051s。SELECT count(*) as count FROM test2 WHERE id ='321321'
:0.00033879280090332s。SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321')
:0.00023889541625977s。SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1)
:0.00020313262939453s。(もっと早く)SELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
select 1 ... limit 1
、selectで囲むのは無意味です
SELECT 1 FROM test WHERE ...
、SELECT EXISTS
その周りにないものです。おそらくその方法で髪の毛はより速くなります。
@ChrisThompsonの回答の短い例
例:
mysql> SELECT * FROM table_1;
+----+--------+
| id | col1 |
+----+--------+
| 1 | foo |
| 2 | bar |
| 3 | foobar |
+----+--------+
3 rows in set (0.00 sec)
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 1) |
+--------------------------------------------+
| 1 |
+--------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 9);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 9) |
+--------------------------------------------+
| 0 |
+--------------------------------------------+
1 row in set (0.00 sec)
エイリアスを使用する:
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
私の研究では、次のスピードで結果が出ていることがわかります。
select * from table where condition=value
(1 total, Query took 0.0052 sec)
select exists(select * from table where condition=value)
(1 total, Query took 0.0008 sec)
select count(*) from table where condition=value limit 1)
(1 total, Query took 0.0007 sec)
select exists(select * from table where condition=value limit 1)
(1 total, Query took 0.0006 sec)
コメントで触れましたが、このような状況では、指摘する価値があります。
SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1
優れている:
SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1
これは、最初のクエリはインデックスで満たすことができるため、2番目のクエリでは行のルックアップが必要になるためです(使用されるインデックスにテーブルの列がすべて含まれている場合を除く)。
LIMIT
句を追加すると、行を見つけた後にエンジンを停止できます。
最初のクエリは次のようになります。
SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)
これは同じ信号をエンジンに送信します(1 / *はここでは違いはありません)が、使用時に習慣を強化するために1を書きますEXISTS
:
SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)
EXISTS
行が一致しないときに明示的な戻りが必要な場合は、ラッピングを追加することは意味があります。
COUNTのかもしれません著しく、しかし限り、望ましい結果を得るように、両者が十分でなければなりませんが、クエリは、高速です。
id
行の自動インクリメント主キー()が存在する場合と存在0
しない場合の取得が非常に便利な場合があります。
これを単一のクエリで実行する方法は次のとおりです。
SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...
IFNULL(id, 0)
代わりにここで使用しないのはなぜCOUNT(*)
ですか?
InnoDB以外のテーブルでは、情報スキーマテーブルを使用することもできます。
と一緒に行きCOUNT(1)
ます。その行の少なくとも1つの列が!= NULLであるかどうかをテストするCOUNT(*)
ためのCOUNT(*)
テストよりも高速です。特に条件(WHERE
節)が既に整っているため、これは必要ありません。COUNT(1)
代わりにの有効性1
をテストします。これは常に有効であり、テストにかかる時間が大幅に短縮されます。
または、生のSQLパーツを条件に挿入して、 'conditions' => array( 'Member.id NOT IN(SELECT Membership.member_id FROM memberships AS Membership))とすることができます。
COUNT(*)
MySQLで最適化されているため、一般的に言えば、前のクエリはより高速になる可能性があります。
...EXISTS( SELECT 1/0 FROM someothertable)
ます。SQL ServerとOracleの場合-EXISTSは1+以上のWHERE条件に基づいてブール値をテストするだけなので、*、1、またはNULLを使用しても違いはありません。