Ich versuche herauszufinden, ob eine Zeile in einer Tabelle vorhanden ist. Mit MySQL ist es besser, eine Abfrage wie folgt durchzuführen:
SELECT COUNT(*) AS total FROM table1 WHERE ...
und prüfen Sie, ob die Summe nicht Null ist oder ob es besser ist, eine Abfrage wie folgt durchzuführen:
SELECT * FROM table1 WHERE ... LIMIT 1
und prüfen, ob Zeilen zurückgegeben wurden?
In beiden Abfragen verwendet die WHERE-Klausel einen Index.
sql
mysql
performance
exists
Bernard Chen
quelle
quelle
...EXISTS( SELECT 1/0 FROM someothertable)
. Für SQL Server und Oracle macht es keinen Unterschied, *, 1 oder NULL zu verwenden, da EXISTS nur einen Booleschen Wert testet, der auf 1+ der übereinstimmenden WHERE-Kriterien basiert.SELECT 1 FROM table1 WHERE col = $var LIMIT 1
ist schneller als Ihre Abfrage. Was ist der Vorteil Ihrer Anfrage?Ich habe kürzlich einige Untersuchungen zu diesem Thema durchgeführt. Die Art und Weise der Implementierung muss unterschiedlich 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 texte LIKE '%something%' LIMIT 1
mitmysql_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
mitmysql_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)quelle
SELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
select 1 ... limit 1
, ist es nutzlos, mit Select zu umgebenSELECT 1 FROM test WHERE ...
, ohne es zuSELECT EXISTS
umgehen. Vermutlich ist ein Haar so schneller.Ein kurzes Beispiel für die Antwort von @ ChrisThompson
Beispiel:
Verwenden eines Alias:
quelle
In meiner Forschung kann ich feststellen, dass das Ergebnis der folgenden Geschwindigkeit folgt.
quelle
Ich halte es für erwähnenswert, obwohl in den Kommentaren darauf hingewiesen wurde, dass in dieser Situation:
Ist überlegen:
Dies liegt daran, dass die erste Abfrage vom Index erfüllt werden kann, während die zweite eine Zeilensuche erfordert (es sei denn, möglicherweise befinden sich alle Spalten der Tabelle im verwendeten Index).
Durch Hinzufügen der
LIMIT
Klausel kann die Engine gestoppt werden, nachdem eine Zeile gefunden wurde.Die erste Abfrage sollte vergleichbar sein mit:
Was die gleichen Signale an den Motor sendet (1 / * macht hier keinen Unterschied), aber ich würde trotzdem die 1 schreiben, um die Gewohnheit bei der Verwendung zu verstärken
EXISTS
:Es kann sinnvoll sein, die
EXISTS
Umhüllung hinzuzufügen , wenn Sie eine explizite Rückgabe benötigen, wenn keine Zeilen übereinstimmen.quelle
Schlagen Sie vor, dass Sie nicht verwenden,
Count
da count immer zusätzliche Ladevorgänge für die Datenbankverwendung ausführtSELECT 1
und 1 zurückgibt, wenn Ihr Datensatz genau dort ist, andernfalls null zurückgibt und Sie damit umgehen können.quelle
Eine COUNT- Abfrage ist schneller, wenn auch möglicherweise nicht merklich, aber um das gewünschte Ergebnis zu erzielen, sollten beide ausreichend sein.
quelle
Manchmal ist es sehr praktisch, den Auto-Inkrement-Primärschlüssel (
id
) der Zeile abzurufen, wenn er vorhanden ist und0
nicht.So geht das in einer einzigen Abfrage:
quelle
IFNULL(id, 0)
hier anstelle des verwendenCOUNT(*)
?Für Nicht-InnoDB-Tabellen können Sie auch die Informationsschematabellen verwenden:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html
quelle
Ich würde mitgehen
COUNT(1)
. Es ist schneller alsCOUNT(*)
weilCOUNT(*)
Tests, um festzustellen, ob mindestens eine Spalte in dieser Zeile! = NULL ist. Das brauchen Sie nicht, vor allem, weil Sie bereits eine Bedingung (dieWHERE
Klausel) haben.COUNT(1)
testet stattdessen die Gültigkeit von1
, was immer gültig ist und viel weniger Zeit zum Testen benötigt.quelle
Oder Sie können einen unformatierten SQL-Teil in Bedingungen einfügen, sodass ich 'Bedingungen' => Array habe ('Member.id NOT IN (SELECT Membership.member_id FROM Mitgliedschaften AS Mitgliedschaft)')
quelle
COUNT(*)
sind in MySQL optimiert, sodass die vorherige Abfrage im Allgemeinen wahrscheinlich schneller ist.quelle