SQL Syntax optimieren
Twilo
- datenbank
0 Vinzenz Mai0 Twilo
0 Ilja0 Twilo
Hallo,
welcher Syntax ist eigentlich besser?
-----------------
SELECT DISTINCT ROUND((
(groesse._breite / 1000 * groesse._hoehe / 1000* auflage._auflage * gewicht._bedrgewicht/1000 * groesse._bedrkosten) +
((farbe._vorderfarbe + farbe._rueckfarbe) * produkt._plattenkosten) +
((((farbe._vorderfarbe + farbe._rueckfarbe) * produkt._ruestzeitproplatte/60) + ((auflage._auflage / CEIL(produkt._bogengroesse / (groesse._breite / 1000 * groesse._hoehe / 1000 * 1.1))) / produkt._maschinengeschwindigkeit) + produkt._einrichtzeit/60) * produkt._maschinenstundensatz) +
(produkt._bogengroesse * gewicht._bedrgewicht/1000 * groesse._bedrkosten * produkt._einrichtboegen) +
ceil(groesse._breite / 1000 * groesse._hoehe / 1000 * auflage._auflage * gewicht._bedrgewicht/1000 * versandart._versdandt) *
faktor._faktor), 2) AS preis
FROM `t1_produkt` AS produkt, `t1_fracht` AS ffracht
INNER JOIN t1_gewinnfaktor AS faktor ON faktor._gewinnfaktor_id = produkt._gewinnfaktor_id
INNER JOIN t1_produkt_has_farbe ON t1_produkt_has_farbe._produkt_id = produkt._produkt_id
INNER JOIN t1_farbe AS farbe ON farbe._farb_id = t1_produkt_has_farbe._farb_id
INNER JOIN t1_produkt_has_versandart ON t1_produkt_has_versandart._produkt_id = produkt._produkt_id
INNER JOIN t1_versandart AS versandart ON versandart._versandart_id = t1_produkt_has_versandart._versandart_id
INNER JOIN t1_produkt_has_auflage ON t1_produkt_has_auflage._produkt_id = produkt._produkt_id
INNER JOIN t1_auflage AS auflage ON auflage._auflage_id = t1_produkt_has_auflage._auflage_id
INNER JOIN t1_produkt_has_gewicht ON t1_produkt_has_gewicht._produkt_id = produkt._produkt_id
INNER JOIN t1_gewicht AS gewicht ON gewicht._gewicht_id = t1_produkt_has_gewicht._gewicht_id
INNER JOIN t1_produkt_has_groesse ON t1_produkt_has_groesse._produkt_id = produkt._produkt_id
INNER JOIN t1_groesse AS groesse ON groesse._groesse_id = t1_produkt_has_groesse._groesse_id
INNER JOIN t1_fracht_has_produkt AS fprodukt ON fprodukt._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_farbe AS ffarbe ON ffarbe._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_gewicht AS fgewicht ON fgewicht._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_groesse AS fgroesse ON fgroesse._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_auflage AS fauflage ON fauflage._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_versandart AS fversandart ON fversandart._fracht_id = ffracht._fracht_id
WHERE produkt._produkt_id = 3 AND gewicht._gewicht_id = 1 AND groesse._groesse_id = 6 AND farbe._farb_id = 3 AND auflage._auflage_id = 1 AND versandart._versandart_id = 1
-----------------
oder dieser
-----------------
SELECT DISTINCT ROUND((
(groesse._breite / 1000 * groesse._hoehe / 1000* auflage._auflage * gewicht._bedrgewicht/1000 * groesse._bedrkosten) +
((farbe._vorderfarbe + farbe._rueckfarbe) * produkt._plattenkosten) +
((((farbe._vorderfarbe + farbe._rueckfarbe) * produkt._ruestzeitproplatte/60) + ((auflage._auflage / CEIL(produkt._bogengroesse / (groesse._breite / 1000 * groesse._hoehe / 1000 * 1.1))) / produkt._maschinengeschwindigkeit) + produkt._einrichtzeit/60) * produkt._maschinenstundensatz) +
(produkt._bogengroesse * gewicht._bedrgewicht/1000 * groesse._bedrkosten * produkt._einrichtboegen) +
ceil(groesse._breite / 1000 * groesse._hoehe / 1000 * auflage._auflage * gewicht._bedrgewicht/1000 * versandart._versdandt) *
faktor._faktor), 2) AS preis
FROM `t1_produkt` AS produkt
INNER JOIN t1_gewinnfaktor AS faktor ON faktor._gewinnfaktor_id = produkt._gewinnfaktor_id
INNER JOIN t1_produkt_has_farbe ON t1_produkt_has_farbe._produkt_id = produkt._produkt_id
INNER JOIN t1_farbe AS farbe ON farbe._farb_id = t1_produkt_has_farbe._farb_id
INNER JOIN t1_produkt_has_versandart ON t1_produkt_has_versandart._produkt_id = produkt._produkt_id
INNER JOIN t1_versandart AS versandart ON versandart._versandart_id = t1_produkt_has_versandart._versandart_id
INNER JOIN t1_produkt_has_auflage ON t1_produkt_has_auflage._produkt_id = produkt._produkt_id
INNER JOIN t1_auflage AS auflage ON auflage._auflage_id = t1_produkt_has_auflage._auflage_id
INNER JOIN t1_produkt_has_gewicht ON t1_produkt_has_gewicht._produkt_id = produkt._produkt_id
INNER JOIN t1_gewicht AS gewicht ON gewicht._gewicht_id = t1_produkt_has_gewicht._gewicht_id
INNER JOIN t1_produkt_has_groesse ON t1_produkt_has_groesse._produkt_id = produkt._produkt_id
INNER JOIN t1_groesse AS groesse ON groesse._groesse_id = t1_produkt_has_groesse._groesse_id
INNER JOIN t1_fracht AS ffracht ON ffracht._fracht_id = fprodukt._fracht_id
INNER JOIN t1_fracht_has_produkt AS fprodukt ON fprodukt._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_farbe AS ffarbe ON ffarbe._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_gewicht AS fgewicht ON fgewicht._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_groesse AS fgroesse ON fgroesse._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_auflage AS fauflage ON fauflage._fracht_id = ffracht._fracht_id
INNER JOIN t1_fracht_has_versandart AS fversandart ON fversandart._fracht_id = ffracht._fracht_id
WHERE produkt._produkt_id = 3 AND gewicht._gewicht_id = 1 AND groesse._groesse_id = 6 AND farbe._farb_id = 3 AND auflage._auflage_id = 1 AND versandart._versandart_id = 1
-----------------
kann man unter MySQL 4.1 die Formel in Zwischenschritte untergliedern?
groesse._breite / 1000 * groesse._hoehe / 1000* auflage._auflage * gewicht._bedrgewicht/1000 * groesse._bedrkosten
kommt z.B. 3mal vor
beide Abfragen brauchen laut phpMyAdmin ca. 0.0035 Sekunden
Gibt es eine Möglichkeit, wie man die Abfrage allgemein optimieren kann?
Die SQL Befehle ohne DISTINCT geben 41.280 Datensätze zurück...
ich fage mich wieso... eigentlich dürfte nur einer rauskommen
ist da irgendwo ein Join Problem, dass er soviele (immer das gleiche Ergebnis) Datensätze anzeigt?
mfg
Twilo
Bitte Twilo,
welcher Syntax ist eigentlich besser?
das heißt: "Welche Syntax ist eigentlich besser?"!
Zwei ellenlange Statements, einziger Unterschied der CROSS JOIN im ersten Fall, der INNER JOIN im zweiten Fall, warum machst Du es Deinen potentiellen Helfern so schwer? Wenn ein INNER JOIN existiert, dann schreib' das auch hin. Also ist meiner Meinung nach die zweite Variante sauberer (und portabler). Der Umgang von MySQL mit CROSS JOINs variiert zwischen MySQL-Versionen und steht zum Teil im Widerspruch zu den SQL-Standards.
kann man unter MySQL 4.1 die Formel in Zwischenschritte untergliedern?
groesse._breite / 1000 * groesse._hoehe / 1000* auflage._auflage * gewicht._bedrgewicht/1000 * groesse._bedrkosten
kommt z.B. 3mal vor
Was hast Du versucht?
beide Abfragen brauchen laut phpMyAdmin ca. 0.0035 Sekunden
Gibt es eine Möglichkeit, wie man die Abfrage allgemein optimieren kann?
Frag' die Datenbank, nutze EXPLAIN.
Die SQL Befehle ohne DISTINCT geben 41.280 Datensätze zurück...
ich fage mich wieso... eigentlich dürfte nur einer rauskommen
warum? Woher sollen wir das wissen? Du hast uns keinen einzigen Deiner Datensätze verraten. Offensichtlich gibt es eben 41.280 verschiedene Möglichkeiten, diese Datensätze in Deinem komplexen JOIN miteinander zu kombinieren, wobei stets der gleiche Preis rauskommt. Wo ist das Problem? Hast Du Rouvens und meinen Artikel zu JOINs gelesen?
ist da irgendwo ein Join Problem, dass er soviele (immer das gleiche Ergebnis) Datensätze anzeigt?
Möglicherweise hast Du ein Verständnisproblem, was JOINs betrifft - und machst falsche Annahmen. Zwar hat auch MySQL 4.1 Verständnisproblem, was JOINs betrifft und liefert in bestimmten Fällen systematisch falsche Ergebnisse - aber nicht bei ausschließlicher Verwendung von INNER JOINs wie in Deinem Fall.
Freundliche Grüße
Vinzenz
Hallo,
welcher Syntax ist eigentlich besser?
das heißt: "Welche Syntax ist eigentlich besser?"!
ok ;-)
Zwei ellenlange Statements, einziger Unterschied der CROSS JOIN im ersten Fall, der INNER JOIN im zweiten Fall, warum machst Du es Deinen potentiellen Helfern so schwer? Wenn ein INNER JOIN existiert, dann schreib' das auch hin. Also ist meiner Meinung nach die zweite Variante sauberer (und portabler). Der Umgang von MySQL mit CROSS JOINs variiert zwischen MySQL-Versionen und steht zum Teil im Widerspruch zu den SQL-Standards.
kann man unter MySQL 4.1 die Formel in Zwischenschritte untergliedern?
groesse._breite / 1000 * groesse._hoehe / 1000* auflage._auflage * gewicht._bedrgewicht/1000 * groesse._bedrkosten
kommt z.B. 3mal vor
Was hast Du versucht?
bis jetzt noch nichts, da ich unter mysql.com kein passenden Abschnitt gefunden habe
beide Abfragen brauchen laut phpMyAdmin ca. 0.0035 Sekunden
Gibt es eine Möglichkeit, wie man die Abfrage allgemein optimieren kann?
Frag' die Datenbank, nutze EXPLAIN.
die Ausgabe von EXPLAIN sieht bei beiden wie folgt aus
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE produkt const PRIMARY,_gewinnfaktor_FKindex PRIMARY 4 const 1 Using temporary
1 SIMPLE faktor const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1_produkt_has_farbe const PRIMARY,_farb_FKindex,_produkt_FKindex PRIMARY 8 const,const 1 Using index
1 SIMPLE farbe const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1_produkt_has_versandart const PRIMARY,_versandart_FKindex,_produkt_FKindex PRIMARY 8 const,const 1 Using index
1 SIMPLE versandart const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1_produkt_has_auflage const PRIMARY,_produkt_FKindex,_auflage_FKindex PRIMARY 8 const,const 1 Using index
1 SIMPLE auflage const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1_produkt_has_gewicht const PRIMARY,_gewicht_FKindex,_produkt_FKindex PRIMARY 8 const,const 1 Using index
1 SIMPLE gewicht const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1_produkt_has_groesse const PRIMARY,_produkt_FKindex,_groesse_FKindex PRIMARY 8 const,const 1 Using index
1 SIMPLE groesse const PRIMARY PRIMARY 4 const 1
1 SIMPLE ffracht index PRIMARY _aktiv_status_FKindex 1 NULL 3 Using index; Distinct
1 SIMPLE fprodukt ref _fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 1 Using index; Distinct
1 SIMPLE fversandart ref PRIMARY,_fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 1 Using index; Distinct
1 SIMPLE fgewicht ref PRIMARY,_fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 3 Using index; Distinct
1 SIMPLE fgroesse ref PRIMARY,_fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 3 Using index; Distinct
1 SIMPLE fauflage ref PRIMARY,_fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 3 Using index; Distinct
1 SIMPLE ffarbe ref PRIMARY,_fracht_FKindex _fracht_FKindex 4 usrdb_schwetbq_druck.ffracht._fracht_id 3 Using index; Distinct
Die SQL Befehle ohne DISTINCT geben 41.280 Datensätze zurück...
ich fage mich wieso... eigentlich dürfte nur einer rauskommen
warum? Woher sollen wir das wissen? Du hast uns keinen einzigen Deiner Datensätze verraten. Offensichtlich gibt es eben 41.280 verschiedene Möglichkeiten, diese Datensätze in Deinem komplexen JOIN miteinander zu kombinieren, wobei stets der gleiche Preis rauskommt. Wo ist das Problem? Hast Du Rouvens und meinen Artikel zu JOINs gelesen?
Möglicherweise hast Du ein Verständnisproblem, was JOINs betrifft - und machst falsche Annahmen. Zwar hat auch MySQL 4.1 Verständnisproblem, was JOINs betrifft und liefert in bestimmten Fällen systematisch falsche Ergebnisse - aber nicht bei ausschließlicher Verwendung von INNER JOINs wie in Deinem Fall.
könntest du bitte den Link posten?
mfg
Twilo
yo,
welcher Syntax ist eigentlich besser?
wie Vinzenz schon ansprach, ist der unterschied der beiden tabellen, dass in der ersten abfrage eine JOIN bedingung fehlt, nämlich von Tabelle "t1_fracht AS ffracht". ich denke mal, du hast sie nur vergessen hinzuschreiben oder fehlt sie tatsächlich ?
beide Abfragen brauchen laut phpMyAdmin ca. 0.0035 Sekunden
ob man nun expliziet die INNER JOIN schreibweise benutzt oder alle JOIN bedingungen in die WHERE klausel mit rein nimmt, ist nur eine frage der übersicht. für die ausführungsgeschwindigkeit spielt sie keine rolle. deine zeitmessung bestätigt diese annahme.
Gibt es eine Möglichkeit, wie man die Abfrage allgemein optimieren kann?
das hängt in erster linie von deinem datendesign und die art der daten ab. ohne es genau zu wissen, sollte man dein daten-design sollte zumindestens einer weiteren prüfung unterziehen. und auch die tabellennamen scheinen mir nicht ganz sinnvoll zu sein.
Die SQL Befehle ohne DISTINCT geben 41.280 Datensätze zurück...
ich fage mich wieso... eigentlich dürfte nur einer rauskommen
ist da irgendwo ein Join Problem, dass er soviele (immer das gleiche Ergebnis) Datensätze anzeigt?
dass die datensätze gleich sind, das hängt mit der ausgabe deiner spalten zusammen. würdest du mehr spalten von verschienden tabellen der abfrage ausgeben, würde dir auffallen, dass sich nun nicht mehr alle datensätze gleichen. das liegt daran, dass ein produkt ganz offensichtlich verschiedene eigenschaften besitzt, die in mehrere tabellen aufgeteilt sind. jede dieser eigenschaften wird nun als ein datensatz dargestellt.
Ilja
Hallo,
Die SQL Befehle ohne DISTINCT geben 41.280 Datensätze zurück...
ich fage mich wieso... eigentlich dürfte nur einer rauskommen
ist da irgendwo ein Join Problem, dass er soviele (immer das gleiche Ergebnis) Datensätze anzeigt?
dass die datensätze gleich sind, das hängt mit der ausgabe deiner spalten zusammen. würdest du mehr spalten von verschienden tabellen der abfrage ausgeben, würde dir auffallen, dass sich nun nicht mehr alle datensätze gleichen. das liegt daran, dass ein produkt ganz offensichtlich verschiedene eigenschaften besitzt, die in mehrere tabellen aufgeteilt sind. jede dieser eigenschaften wird nun als ein datensatz dargestellt.
danke für den Tipp, ich werde mal mehrere Spalten abfragen
mfg
Twilo