it-swarm.com.de

Am besten testen Sie, ob eine Zeile in einer MySQL-Tabelle vorhanden ist

Ich versuche herauszufinden, ob eine Zeile in einer Tabelle vorhanden ist. Wenn Sie MySQL verwenden, ist es besser, eine Abfrage wie die folgende durchzuführen:

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

und prüfen Sie, ob die Summe ungleich Null ist oder ob es besser ist, eine Abfrage wie die folgende durchzuführen:

SELECT * FROM table1 WHERE ... LIMIT 1

und überprüfen Sie, ob Zeilen zurückgegeben wurden?

In beiden Abfragen verwendet die WHERE-Klausel einen Index.

305
Bernard Chen

Sie könnten es auch mit versuchen

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

per die Dokumentation

Nachstehend ein Kommentar:

SELECT EXISTS(SELECT 1 FROM table1 WHERE ...)
432
Chris Thompson

Ich habe in letzter Zeit einige Nachforschungen zu diesem Thema angestellt. Die Art 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 1 Million Einträgen haben. 37 Einträge sind gleich 'etwas':

  • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1 Mit mysql_num_rows(): 0.039061069488525s. (SCHNELLER)
  • 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. (SCHNELLER)
169
Laurent W.

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)

Verwenden eines Alias:

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

In meiner Forschung kann ich feststellen, dass das Ergebnis immer schneller wird.

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) 
10
shihab mm

Ich halte es für erwähnenswert, darauf hinzuweisen, dass in dieser Situation, obwohl dies in den Kommentaren angesprochen wurde:

SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1

Ist überlegen gegenüber:

SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1

Dies liegt daran, dass die erste Abfrage vom Index erfüllt werden kann, während für die zweite Abfrage eine Zeilensuche erforderlich ist (es sei denn, möglicherweise befinden sich alle Spalten der Tabelle im verwendeten Index).

Durch Hinzufügen der LIMIT -Klausel kann die Engine nach dem Auffinden einer Zeile angehalten werden.

Die erste Abfrage sollte vergleichbar sein mit:

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

Was die gleichen Signale an die Engine sendet (1/* macht hier keinen Unterschied), aber ich würde trotzdem die 1 schreiben, um die Gewohnheit bei der Verwendung von EXISTS zu verstärken:

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

Es kann sinnvoll sein, den Zeilenumbruch EXISTS hinzuzufügen, wenn Sie eine explizite Rückgabe benötigen, wenn keine Zeilen übereinstimmen.

7
Arth

Schlagen Sie vor, Count nicht zu verwenden, da count für db use SELECT 1 Immer zusätzliche Ladevorgänge verursacht und 1 zurückgibt, wenn Ihr Datensatz genau dort ist, andernfalls null zurückgibt und Sie damit umgehen können es.

4
Fatih Karatana

Manchmal ist es sehr praktisch, den Auto-Inkrement-Primärschlüssel (id) der Zeile abzurufen, falls vorhanden, und 0 wenn nicht.

So können Sie dies in einer einzelnen Abfrage tun:

SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...
2
Zaxter

Eine COUNT Abfrage ist schneller, wenn auch vielleicht nicht merklich, aber so weit wie Um das gewünschte Ergebnis zu erzielen, sollten beide ausreichen.

0
jaywon

Ich würde mit COUNT(1) gehen. Es ist schneller als COUNT(*), da COUNT(*) prüft, ob mindestens eine Spalte in dieser Zeile! = NULL ist. Das brauchen Sie nicht, vor allem, weil Sie bereits eine Bedingung haben (die WHERE -Klausel). COUNT(1) testet stattdessen die Gültigkeit von 1, das immer gültig ist und viel weniger Zeit zum Testen benötigt.

0
Felix