MySQL: Lassen sich hier 2 SQL Statements vermeiden?
LarsSW
- datenbank
0 Klaus0 Stefan Eickhoff0 Cruz
Hallo,
ich habe so eine Art Privatnachrichten-System. Im Posteingang frage ich zb. alle Nachrichten ab, die an Benutzer "Fritz" gesendet wurden. Doppelte Einträge spielen dabei keine Rolle, denn es kann ja gut sein, dass Benutzer "Heinz" durchaus mehrere Nachrichten an "Fritz" gesendet hat.
Nun habe ich aber auf der HTML-Seite über der Nachrichtenliste noch ein SELECT-Menü, in dem alle Benutzer aufgelistet sind, die "Fritz" eine Nachricht geschickt haben. Dort soll "Heinz" natürlich nur einmal drinstehen.
Bisher hab ich dafür 2 Abfragen verwendet: Die sind im Prinzip identisch, die eine fragt alle Nachrichten ab, die zweite tut das auch, nur dass im SQL-Statement "DISTINCT" verwendet wurde, damit jeder Benutzer nur einmal aufgelistet wird.
Meine Frage: Ist das sinnvoll? Oder sollte ich doch nur eine Abfrage machen, und dann bei jeder Zeile einmal überprüfen, ob der Benutzer schon der SELECT-Liste zugefügt wurde?
Diese Überprüfung sähe so aus:
while($row = mysql_fetch_array($result))
{
if(strpos($selectListe,$row['user']) !== false)
$selectListe .= ",".$row['user'];
// Hier werden dann die restlichen Variablen gespeichert
}
Ich frage mich also: Was ist schneller? In jeder Zeile, die abgearbeitet wird, eine strpos() Überprüfung, oder einfach ein zweites SQL-Statement?
Beste Grüße
Lars
Hallo,
ich versteh nicht ganz dein Problem.
Wieso funktioniert ein einfaches DESTINCT (oder GROUP BY) bei dir nicht?
Damit bekommst du doch nur jeden Namen einfach.
Grüße
Klaus
Hallo Lars,
ein einfache Möglichkeit wäre ein Array zu verwenden:
$stack = array();
while([...]):
$stack[$row['user']] = 1;
endwhile;
$userlist = join (', ', array_keys($stack));
Viele Grüße
Stefan
Meine Frage: Ist das sinnvoll? Oder sollte ich doch nur eine Abfrage machen, und dann bei jeder Zeile einmal überprüfen, ob der Benutzer schon der SELECT-Liste zugefügt wurde?
Ich frage mich also: Was ist schneller? In jeder Zeile, die abgearbeitet wird, eine strpos() Überprüfung, oder einfach ein zweites SQL-Statement?
Ich halte das auf jeden Fall für sinnvoll das mit zwei Abfragen zu lösen, weil das Programm dann einfacher und klarer ist. Jeder sieht sofort, aha, hier wird der Dropdown mit den Namen gefüllt und dort werden die Nachrichten aufgelistet. Es ist auch deswegen besser so, weil die zwei Komponenten dann unabhängig voneinander sind und wenn du eins davon irgendwie ändern musst, funktioniert das andere immer noch.
Schneller ist es auch, obwohl ich nicht glaube, dass du es mit einer Datenmenge zu tun hast, wo du einen spürbaren Unterschied erreichen kannst.
Cruz
Hi Cruz,
Ich halte das auf jeden Fall für sinnvoll das mit zwei Abfragen zu lösen, [...]
Es ist wohl bis zu einem gewissen Grade Geschmacksache, aber ich widerspreche aus folgenden Gründen:
Es ist auch deswegen besser so, weil die zwei Komponenten dann unabhängig voneinander sind
Die Komponenten sind von vornherein nicht unabhängig. In beiden Listen stehen Namen, die von derselben Liste von Nachrichten kommen. Macht man zwei Abfragen, hat man zwei potenzielle Fehlerquellen, um gewissermaßen zwei verschiedene Versionen derselben Namensliste zu erzeugen. Da sehe ich keinen Grund für.
Schneller ist es auch
Warum? Ich habs nicht getestet, aber ich kann es mir nicht recht vorstellen. Du hast etwa die Funktion array_unique()
, mit der ich es machen würde, gegen den Algorithmus des DBMS, doppelte Namen zu streichen. Die PHP-Version dürfte etwas, aber unwesentlich, langsamer sein, weil sie interne Typkonvertierungen macht (bzw. zumindest den Typ prüft), aber man spart den Datenbanktransfer für eine zweite Abfrage.
Meine Meinung wäre also: eine Abfrage reicht.
Viele Grüße
der Bademeister
Hallo,
Ich halte das auf jeden Fall für sinnvoll das mit zwei Abfragen zu lösen, [...]
Es ist wohl bis zu einem gewissen Grade Geschmacksache, aber ich widerspreche aus folgenden Gründen:
Die Komponenten sind von vornherein nicht unabhängig. In beiden Listen stehen Namen, die von derselben Liste von Nachrichten kommen. Macht man zwei Abfragen, hat man zwei potenzielle Fehlerquellen, um gewissermaßen zwei verschiedene Versionen derselben Namensliste zu erzeugen. Da sehe ich keinen Grund für.
Naja, es sind unterschiedliche Views der selben Daten. Vielleicht will man ja mal die Nachrichten nach Datum sortieren und oh misst, dann sortieren sich die Namen ja auch um, die man ja eigentlich alphabetisch sortiert haben wollte. Mit einem SELECT treten dann solche Effekte auf.
Die zwei Fehlerquellen sind so oder so vorhanden, nur sind sie bei einer Abfrage auf eine Stelle konzetriert. So oder so, man muss sowohl auf die Namen, als auf die Nachrichten Acht geben, damit sie richtig funktionieren. Bei getrennten Abfragen hast du wenigstens zwei Module, die jeder für sich genommen einfacher sind, als die eine Abfrage. Wenn man sie dann geschafft hat, dann läufts auch und wenn man nur einen der beiden ändert, wird der andere nicht beeinflusst. Im Gegensatz wenn man alles in einer Abfrage macht.
Und so kann man einen floh zum Elephanten diskturieren. :) Aber es geht ja hier um Stil und das ist wichtig.
Schneller ist es auch
Gemessen habe ich es auch nicht, es ist mal wieder so ein Bauchgefühl. Der OP hat es ja mit Stringoperationen gelöst und langsamer als das geht es ja kaum. Datenbankabfragen hingegen sind von Profis bis zum Anschlag optimiert, Handles werden gecachet usw. Sie sind schnell. Ist eh egal, wenn die Laufzeit eines Skriptes maximal 1% der gesamten Zeit vom Klick bis zur kompletten Übertragung der Daten ausmacht. Wenn du da noch 2 - 3 Millisekunden rausholst, dann kannst du dir aber echt mal auf die Schulter klopfen. Da schreibst du besser langsameren aber lesbaren Code, oder zur Not halt irgendeine Lösung mit der du selbst als Anfänger klar kommst.
Cruz
Hallo,
Naja, es sind unterschiedliche Views der selben Daten. Vielleicht will man ja mal die Nachrichten nach Datum sortieren und oh misst, dann sortieren sich die Namen ja auch um, die man ja eigentlich alphabetisch sortiert haben wollte. Mit einem SELECT treten dann solche Effekte auf.
Stimmt, das hatte ich gar nicht geschrieben: Die Abfrage, mit der die Nachrichten abgerufen werden, kann der Benutzer noch beeinflussen, indem er bestimmte Sortierungsfilter o.ä. einstellt.
Ich denke grade auch aus diesem Grund werde ich bei 2 getrennten Abfragen bleiben. Vielen Dank!
Beste Grüße
Lars