|
|
|
|
Schönen guten Morgen
|
|
|
|
|
|
|
| Zitat von Achse-des-boesen
| Zitat von GH@NDI
Da kommst du an einem fiesen Subselect nicht drumherum ![Breites Grinsen](img/smilies/biggrin.gif) | |
Zwei Joins?
Ich habe hier zumindest in meinem Notizblock einen Query stehen der 3 Joins über insgesamt 4 Tabellen hat und prima funktioniert.
/: Okay, 3 Lösungen...das schreit nach einen Vergleich ob und wie gut sie laufen ![Augenzwinkern](img/smilies/wink.gif)
| |
Deins ist ja schon durch die Definition falsch. ![Breites Grinsen](img/smilies/biggrin.gif)
Er will alle Schüler die Fußball UND Schwimmen ![Breites Grinsen](img/smilies/biggrin.gif)
Und mein Query tut nicht, verwirrender Weise. Denn
|
Code: |
SELECT s.name, h1.hobby
FROM schueler s
LEFT JOIN relation r ON r.schueler_ID = s.ID
LEFT JOIN hobby h1 ON r.hobby_ID = h1.ID
WHERE
3 IN (
SELECT h.id
FROM hobby h
WHERE h.id = r.hobby_id
)
LIMIT 0 , 30
|
|
Gibt Sabine und Christian ja, die ja beide Schwimmen.
Und
|
Code: |
SELECT s.name, h1.hobby
FROM schueler s
LEFT JOIN relation r ON r.schueler_ID = s.ID
LEFT JOIN hobby h1 ON r.hobby_ID = h1.ID
WHERE
2 IN (
SELECT h.id
FROM hobby h
WHERE h.id = r.hobby_id
)
LIMIT 0 , 30
|
|
gibt mir Sabine und SirSiggi aus die beide Fußball spielen.
Verknüpfe ich aber die beiden Subselects mit einem AND kommt niemand mehr raus
|
|
|
|
|
|
|
|
|
|
|
| Zitat von GH@NDI
Er will alle Schüler die Fußball UND Schwimmen ![Breites Grinsen](img/smilies/biggrin.gif) | | Oh
|
|
|
|
|
|
|
Haha!!! ![Breites Grinsen](img/smilies/biggrin.gif)
|
Code: |
SELECT s.name
FROM schueler s
LEFT JOIN relation r ON r.schueler_ID = s.ID
WHERE
2 IN (SELECT h.id FROM hobby h, relation r2 WHERE r2.schueler_ID = s.ID AND h.id = r2.hobby_id) AND
3 IN (SELECT h.id FROM hobby h, relation r2 WHERE r2.schueler_ID = s.ID AND h.id = r2.hobby_id)
GROUP BY s.name
|
|
Liefert mir die Sabine in 0.0006 Sekunden.
|
|
|
|
|
|
|
|
Code: |
SELECT Schueler.name
FROM Schueler
WHERE
Schueler.ID IN (
SELECT Relation.schuler_id FROM Relation JOIN Hobby ON Hobby.ID = Relation.hobby_id WHERE Hobby.hobby = 'Schwimmen'
)
AND
Schueler.ID IN (
SELECT Relation.schuler_id FROM Relation JOIN Hobby ON Hobby.ID = Relation.hobby_id WHERE Hobby.hobby = 'Fußball'
); |
|
/: Ja, ich suche nach dem Namen, aber da kann man natürlich auch die ID benutzen.
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von Achse-des-boesen am 30.05.2007 12:27]
|
|
|
|
|
|
Interessant, das von Ghandi scheint schneller:
My:
|
Code: |
mysql> explain SELECT Schueler.name FROM Schueler WHERE Schueler.ID IN (SELECT Relation.schuler_id FROM Relation JOIN Hobby ON Hobby.ID = Relation.hobby_id WHERE Hobby.hobby = 'Schwimmen') AND Schueler.ID IN (SELECT Relation.schuler_id FROM Relation JOIN Hobby ON Hobby.ID = Relation.hobby_id WHERE Hobby.hobby = 'Fußball');
+----+--------------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+----------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | Schueler | ALL | NULL | NULL | NULL | NULL | 3 | Using where |
| 3 | DEPENDENT SUBQUERY | Hobby | ALL | NULL | NULL | NULL | NULL | 4 | Using where |
| 3 | DEPENDENT SUBQUERY | Relation | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 2 | DEPENDENT SUBQUERY | Hobby | ALL | NULL | NULL | NULL | NULL | 4 | Using where |
| 2 | DEPENDENT SUBQUERY | Relation | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+--------------------+----------+------+---------------+------+---------+------+------+-------------+
5 rows in set (0.01 sec)
|
|
Ghandis:
|
Code: |
mysql> explain SELECT s.name FROM Schueler s LEFT JOIN Relation r ON r.schuler_id = s.ID WHERE 2 IN (SELECT h.id
FROM Hobby h, Relation r2 WHERE r2.schuler_id = s.ID AND h.id = r2.hobby_id) AND 3 IN (SELECT h.id FROM Hobby h
, Relation r2 WHERE r2.schuler_id = s.ID AND h.id = r2.hobby_id) GROUP BY s.name;
+----+--------------------+-------+------+---------------+------+---------+------+------+-----------------------
-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
|
+----+--------------------+-------+------+---------------+------+---------+------+------+-----------------------
-----------------------+
| 1 | PRIMARY | s | ALL | NULL | NULL | NULL | NULL | 3 | Using where; Using tem
porary; Using filesort |
| 1 | PRIMARY | r | ALL | NULL | NULL | NULL | NULL | 6 |
|
| 3 | DEPENDENT SUBQUERY | h | ALL | NULL | NULL | NULL | NULL | 4 | Using where
|
| 3 | DEPENDENT SUBQUERY | r2 | ALL | NULL | NULL | NULL | NULL | 6 | Using where
|
| 2 | DEPENDENT SUBQUERY | h | ALL | NULL | NULL | NULL | NULL | 4 | Using where
|
| 2 | DEPENDENT SUBQUERY | r2 | ALL | NULL | NULL | NULL | NULL | 6 | Using where
|
+----+--------------------+-------+------+---------------+------+---------+------+------+-----------------------
-----------------------+
6 rows in set (0.00 sec)
|
|
Saltsam, dabei hat er sogar eine Tabelle mehr drin...
|
|
|
|
|
|
|
Das ergebnis bei Explain ist doch aber nicht die Ausführungszeit des erklärten Queries, sondern die Zeit die vergeht um das Query zu erklären?
|
|
|
|
|
|
|
Stimmt, Explain gibt dir bloß eine detaillierte Übersicht.
Aber ich wunder mich immernoch warum dein mehrfaches Where so viel schneller ist als mein Join. Ich vermute zwar, dass sich das Problem auslöst, sobald ich die ID-Splaten als Index definiere, aber trotzdem, wenn man sich das Explain bei dir anschaut und dann mal in die Mysql-Doku guckt:
Using filesort - MySQL muss einen zusätzlichen Durchlauf vornehmen, um zu ermitteln, wie die Datensätze in sortierter Reihenfolge abgerufen werden können.
Using temporary Um die Abfrage aufzulösen, muss MySQL eine Temporärtabelle zur Aufnahme des Ergebnisses erstellen.
Wobei die beiden Sachen jeweils vom Group-By ausgelöst werden.
|
|
|
|
|
|
|
Also ich hab jetzt beide Queries mal durchgejagt. Nach mehrmaligen ausführen brauchen beide nur 0.0001Sekunden in PHPMyAdmin.
Vermutlich wird man erst erkennen können welches schneller ist wenn die Datenbank entsprechend angewachsen ist.
|
|
|
|
|
|
|
Ihr übertreibt es jungs
|
|
|
|
|
|
|
| Zitat von TriggerTG
Ihr übertreibt es jungs ![Augenzwinkern](img/smilies/wink.gif) | |
Denkst du.
Wenn man allerdings auf Tabellen arbeitet die ein paar hundertmillionen Datensätze enthalten spielt es schon eine Rolle ob eine Query 2 Sekunden oder 200 braucht. Und ich bewege mich - immernoch - in Bereichen wo sowas durchaus öfter mal vorkommt. ![Augenzwinkern](img/smilies/wink.gif)
Wobei wir natürlich nicht Mysql einsetzen...
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Achse-des-boesen am 30.05.2007 12:48]
|
|
|
|
|
|
Sondern Ihr benutzt... Bitte setzen Sie den Satz logisch fort.
|
|
|
|
|
|
|
sqllite
|
|
|
|
|
|
|
Wer outet sich und sagt "Access"?
|
|
|
|
|
|
|
Warum Outen?
Access hat durchaus seine Lebensberechtigung
|
|
|
|
|
|
|
|
|
|
|
So, jetzt mal ein wenig Optimierung. Wenn man sich die Spalte "rows" beim Explain anschaut, sieht man wie viele Zeilen die DB beim auflösen des Queries durchlaufen hat. Wenn man nun das Produkt aus diesen Zahlen bildet, bekommt man die Anzahl der Vergleiche, die die DB durchgeführt hat was sich wierrum ziemlich linear in CPU-Zeit niederschlägt.
Unoptimiert waren das...
- bei Ghandi: 3 * 6 * 4 * 6 * 4 * 6 = 10368
- bei mir: 3 * 4 * 6 * 4 * 6 = 1728
Das mein Query anfangs langsamer war lag daran, dass ich mit dem Hobby-Namen gearbeitet habe, wärend Ghandi die ID benutzt hat, intern also ein Binärer-Stringverleich gegen einen Binären Integervergleich stand.
Fägt man jetzt auf sämtliche ID-Spalten in Relation, Hobby und Schueler einen Index hinzu, landet man bei...
- Ghandi: 3 * 6 * 1 * 2 * 1 * 2 = 72
- mir: 3 * 1 * 2 * 1 * 2 = 12
Das ganze ist schonmal ein dramatischer unterschied zu vorher.
Wenn man das jetzt weiter aufschlüsselt, läuft er bei mir einmal komplett durch Schueler und die restlichen Dinge sind einfache Zugriffe über den Index.
Bei Ghandi sieht es ähnlich aus, allerdings müssen die beiden Subselects erst in einer temporären Tabelle gespeichert werden, dessen Länge wiederum das Produkt aus Anzahl der Subselect mal Länge der Schueler ist. Ghandis anfragen wird also bei großen Datenmengen um den Faktor 2*length(Schueler) langsamer sein und wegen der Temporären Tabelle auchnoch viel Ram benötigen ![Augenzwinkern](img/smilies/wink.gif)
Achja, und wir benutzen Sybase.
/: Und wenn ihr meint ich übertreibe: Ich hab gerade mal in unsere Produktionstabelle geschaut und mir mal die Tabelle rausgepickt, in der die Meldepunkte (was ist wann wo) für unsere Produkte gespeichert werden. Im aktiven Bestand sind das 600000 Zeilen und in der History 3Mio (History = die letzten 30 Tage). Das Archiv hab ich jetzt mal rausgelassen, aber darin stehen die Daten der letzten 5 Jahre, sollten also 150-180Mio sein. Wenn man bedenkt, dass das zwar eine der aktivsten Tabellen ist, aber eben nur eine von einer ganze Menge, dann sollte klar sein, warum ich einens etwas anderen Bezug zu sowas habe
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Achse-des-boesen am 30.05.2007 13:38]
|
|
|
|
|
|
hi,
aus irgend einem Grund werden auf dem selbst installierten Apache2 keine meta-Angaben aus dem head gelesen. Dies verhält sich mit mehreren Seiten so, auf anderen Servern funktionieren diese aber. Wo könnte das Problem liegen?
|
|
|
|
|
|
|
Höö? Welche Meta-Angaben? Die, die in einer HTML Datei innerhalb der HEAD-Tags stehen? Wenn diese gemeint sein sollten, darauf hat der verwendete Webserver überaupt keinen Einfluss. ![Breites Grinsen](img/smilies/biggrin.gif)
@Achse
Ich hab ja noch gar nichtmal optimiert...ich hab doch nur geschaut das es geht *bibber*
|
|
|
|
|
|
|
|
|
|
|
| Zitat von Zensiert
Targ :x
Kris
| | Kohle?
|
|
|
|
|
|
|
| Zitat von v!pe
| Zitat von Zensiert
Targ :x
Kris
| | Kohle? ![Augenzwinkern](img/smilies/wink.gif)
| |
Überweise ich dir morgen, wenn es in Ordnung ist. Mein Konto sieht zur Zeit ein wenig rot aus :>
Kris
|
|
|
|
|
|
|
|
|
|
|
Jetzt noch zwei Stunden Bio.
|
|
|
|
|
|
|
| Zitat von GH@NDI
Höö? Welche Meta-Angaben? Die, die in einer HTML Datei innerhalb der HEAD-Tags stehen? Wenn diese gemeint sein sollten, darauf hat der verwendete Webserver überaupt keinen Einfluss. ![Breites Grinsen](img/smilies/biggrin.gif)
@Achse
Ich hab ja noch gar nichtmal optimiert...ich hab doch nur geschaut das es geht *bibber* ![Breites Grinsen](img/smilies/biggrin.gif)
| |
ja diese sind gemeint. Und es kommt mir auch recht merkwürdig vor, aber:
wenn ich die Seite lokal lade funktioniert es, wenn ich sie zB über meinen Space bei Arcor lasse funktioniert es, und bei dem Apache eben nicht. Habs jeweils mit FF und IE6 versucht!
|
|
|
|
|
|
|
Was genau versuchst du denn zu machen?
|
|
|
|
|
|
|
Eben, wie glaubst du denn Festzustellen ob es funtioniert? Was machst du denn da? So ne Zeitgesteuerte Umleitung? Oder so eine Navigationsleiste oben einblenden?
|
|
|
|
|
|
|
| Zitat von Zensiert
| Zitat von v!pe
| Zitat von Zensiert
Targ :x
Kris
| | Kohle? ![Augenzwinkern](img/smilies/wink.gif)
| |
Überweise ich dir morgen, wenn es in Ordnung ist. Mein Konto sieht zur Zeit ein wenig rot aus :>
Kris
| | Solange das sicher ist, ists ok. Will nur nich in 2 Wochen hören: "Oh ne brauch ich doch nich kkthxbaibai"
|
|
|
|
|
|
|
ffffffaasdasdqsaeqsfqasfsq
|
|
|
|
|
|
Thema: Gehirnsalat ( wir unter uns ) |