Prüfen, ob ein bestimmter Datensatz vorhanden ist

Häufig möchte man Prüfen, ob ein bestimmter Datensatz einer MySQL-Tabelle existiert. Dazu hat man mit PHP – wie immer im Leben – mehrere Möglichkeiten. Dieser Beitrag soll die Varianten, die mir in den Sinn gekommen sind, aus Performancesicht untersuchen.

Erstmal kurz die Vorstellung der Kandidaten:

   $einlesen = mysql_query("SELECT ID FROM tabelle WHERE ID='123'");  if(mysql_num_rows($einlesen)==1) echo "ja"; else  echo "nein";     

Bei dieser Variante wird der Primärschlüssel (oder irgendeine andere Spalte) des Datensatzes selektiert. Anschließend wird die Anzahl der zurückgegebenen Datensätze im Result-Set gezählt. Wenn diese 1 beträgt, dann existiert der Datensatz, ansonsten eben nicht. Diese Variante funktioniert nur mit mysql_query(), nicht aber mit mysql_unbuffered_query(). Dazu aber bald mehr in einem Extra-Beitrag über die Unterschiede.

Variante 2 sieht so aus:

 $einlesen = mysql_query("SELECT COUNT(*) FROM hotels WHERE ID='123'"); if(mysql_result($einlesen,0)==1)  echo "ja"; else echo "nein";  

Hier wird das Zählen von MySQL selbst durch die Funktion COUNT() erledigt. Anschließend muss nur noch überprüft werden, ob dieser Wert 1 ist oder nicht. Der Einsatz von mysql_num_rows() ist hier übrigens nicht mehr möglich, da die Anzahl der Zeilen im zurückgegebenen Result-Set immer 1 ist (wenn der Datensatz nicht gefunden wird, ist das Ergebnis 0, aber das ist ja trotzdem 1 Datensatz).

Und die dritte Variante ist wie die zweite, nur dass diesmal nicht mit dem als recht langsam geltenden mysql_result gearbeitet wird, sondern vorher ein mysql_fetch_row() durchgeführt wird, also:

 $einlesen = mysql_query("SELECT COUNT(*) FROM hotels WHERE ID='123'");  $einzeln = mysql_fetch_row($einlesen);  if($einzeln[0]==1)  echo "ja"; else  echo "nein";    

mysql_result gilt als langsam, da man sich mit der Funktion frei im Result-Set fortbewegen kann. Normalerweise nutzt man das nicht, weil diese Flexibilität oft unnötig ist und deshalb stattdessen das Result-Set sequentiell ausgelesen wird, was performanter ist. Da es hier aber sowieso nur ein Element ist und das mysql_fetch_row() praktisch eine zusätzliche Funktion ist, habe ich es mit in den Test genommen, um zu überprüfen, ob der Overhead von mysql_result() schwerer wiegt als das zusätzliche Ausführen von mysql_fetch_row().

Übrigens habe ich im Test noch eine for-Schleife drumrum gebastelt, damit wirklich die Performance der Funktionen den Ausschlag gibt und nicht die eine einzelne Anfrage. Wer Genaueres wissen, möchte, kann sich die benutzten Quelltexte herunterladen.

Das Ergebnis sieht nun folgendermaßen aus:

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
result_mysql_ num_rows.php 90.760508 s 90.761 ms 100 %
result_mysql_ count.php 93.214035 s 93.214 ms 103 % (+ 3%)
result_mysql_ count_fetch.php 94.726209 s 94.726 ms 104 % (+ 4%)

Die schnellste Variante ist demzufolge das Zählen von PHP erledigen zu lassen – per mysql_num_rows(). Die anderen beiden Varianten haben aber Ihre Vorteile, wenn man nicht nur auf das Vorhandensein eines einzelnen Datensatzes prüft, sondern eine große Datenmenge hat. Dann würde das Zählen von MySQL die von PHP auszuwertende Datenmenge nämlich beträchtlich senken


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0