420 Stimmen

Der beste Weg zu testen, ob eine Zeile in einer MySQL-Tabelle existiert

Ich versuche herauszufinden, ob eine Zeile in einer Tabelle existiert. Mit MySQL, ist es besser, eine Abfrage wie diese zu tun:

SELECT COUNT(*) AS total FROM table1 WHERE ...

und prüfen, ob die Summe ungleich Null ist, oder ist es besser, eine Abfrage wie diese zu machen:

SELECT * FROM table1 WHERE ... LIMIT 1

und prüfen, ob Zeilen zurückgegeben wurden?

In beiden Abfragen verwendet die WHERE-Klausel einen Index.

562voto

Chris Thompson Punkte 34220

Sie könnten auch versuchen EXISTS :

SELECT EXISTS(SELECT * FROM table1 WHERE ...)

und pro die Dokumentation können Sie SELECT alles.

Traditionell beginnt eine EXISTS-Subquery mit SELEC aber sie kann auch mit SELECT 5 oder SELECT column1 oder irgendetwas anderem beginnen. M ignoriert die SELECT-Liste in einer solchen Subquery, so dass es keinen Unterschied macht.

245voto

Laurent W. Punkte 3305

Ich habe kürzlich einige Nachforschungen zu diesem Thema angestellt. Die Art und Weise der Implementierung muss anders sein, wenn das Feld ein TEXT-Feld ist, ein nicht eindeutiges Feld.

Ich habe einige Tests mit einem TEXT-Feld durchgeführt. In Anbetracht der Tatsache, dass wir eine Tabelle mit 1M Einträgen haben. 37 Einträge sind gleich "etwas":

  • SELECT * FROM test WHERE text LIKE '%something%' LIMIT 1 mit mysql_num_rows() : 0.039061069488525s. (FASTER)
  • 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.

Aber jetzt, mit einem BIGINT PK-Feld, ist nur ein Eintrag gleich "321321":

  • SELECT * FROM test2 WHERE id ='321321' LIMIT 1 mit 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. (FASTER)

36voto

jaltek Punkte 2342

Ein kurzes Beispiel für die Antwort von @ChrisThompson

Beispiel:

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)

Verwendung eines Alias:

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)

28voto

shihab mm Punkte 455

Bei meinen Nachforschungen konnte ich feststellen, dass das Ergebnis von der Geschwindigkeit abhängt.

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)

22voto

Arth Punkte 12000

Ich halte es für wichtig, darauf hinzuweisen, auch wenn es in den Kommentaren angesprochen wurde, dass in dieser Situation:

SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1

ist überlegen:

SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1

Der Grund dafür ist, dass die erste Abfrage durch den Index erfüllt werden kann, während die zweite eine Zeilensuche erfordert (es sei denn, alle Spalten der Tabelle sind im verwendeten Index enthalten).

Hinzufügen der LIMIT Klausel ermöglicht es der Maschine, nach dem Auffinden einer beliebigen Zeile anzuhalten.

Die erste Abfrage sollte vergleichbar sein mit:

SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)

Das sendet die gleichen Signale an den Motor (1/* macht hier keinen Unterschied), aber ich würde trotzdem die 1 schreiben, um die Gewohnheit zu verstärken, wenn ich EXISTS :

SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)

Es kann sinnvoll sein, die EXISTS wickeln, wenn Sie eine explizite Rückgabe benötigen, wenn keine Zeilen übereinstimmen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X