Ist mein Rechner für tabellenübergreifende SQL-Abfrage zu lahm?
mysqlfan
- datenbank
0 zaphod19840 Frank (no reg)0 fastix®0 EKKi0 mysqlfan0 Ilja
Hallo!
Ich möchte folgende Abfrage mit MySQL machen:
$result = $mysqli->query("SELECT registration.registration, company.companyname, magazine.type FROM registration, company, magazine WHERE registration.registration = '{$_POST['book']}' AND magazine.registrationid = registration.registrationid AND company.companynumber = registration.companynumber");
Das Problem ist: Mein PC verarbeitet diese Anfrage nicht, obwohl sie korrekt formuliert zu sein scheint.
Es handelt sich um 3 Tabellen, von denen jede 500.000 Datensätze á ca. 7-10 Spalten hat.
Nicht nur über das php-Skript, sondern auch im SQL-Abfragefenster bei phpMyAdmin führt folgende Abfrage zu derselben andauernden 100% CPU-Auslastung:
SELECT
registration.registration, company.companyname, magazine.type
FROM
registration, company, magazine
WHERE
registration.registration = 'A12345'
AND
magazine.registrationid = registration.registrationid
AND
company.companynr = registration.companynr
Wenn ich zum Test diese einfache Abfrage aus einer der Tabellen mache (hat ja schließlich immerhin schon 500.000 Zeilen, dann funktioniert dies problemlos:
$result = $mysqli->query("SELECT registration.registration FROM registration WHERE registration.registration = '{$_POST['book']}'");
Der Rechner ist ein 2 GhZ mit 1 GB RAM. Das kann doch nicht die Kiste so überfordern?! Oder liegt es am PC, dass die tabellenübergreifende Suche nicht funktioniert?
Noch ein Hinweis: Ich führe die Abfrage nicht nach Primärschlüsseln aus, falls das hilft.
RegistrationID und Companynr sind ganz normale Tabellenspalten, die nicht als Primärschlüssel definiert sind.
indizes?
Hallo, was sagt "EXPLAIN" oder wie das bei mysql heisst? Evt. erzeugst du aufgrund der nicht expliziten JOIN Syntax ein sehr grosses Kreuzprodukt. Es sieht auf den ersten Blick aber so aus, als möchtest du einen INNER JOIN anwenden. Deshalb empfehle ich dir, die explizite JOIN Syntax zu verwenden und nicht FROM tab1, tab2, tab3 ... nachzulesen in der Doku von mysql. Gruss, Frank
Moin!
Du hast die Antwort selbst gegeben.
Noch ein Hinweis: Ich führe die Abfrage nicht nach Primärschlüsseln aus, falls das hilft.
RegistrationID und Companynr sind ganz normale Tabellenspalten, die nicht als Primärschlüssel definiert sind.
Lege einen Index (es muss nicht der Primärschlüssel sein) auf die jeweils links in den where-clauseln stehenden Spalten:
registration.registration
magazine.registrationid
company.companynr
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix
Mahlzeit mysqlfan,
Ich möchte folgende Abfrage mit MySQL machen:
Du hast also ein Datenbank-(genauer: MySQL-)Problem.
$result = $mysqli->query("SELECT registration.registration, company.companyname, magazine.type FROM registration, company, magazine WHERE registration.registration = '{$_POST['book']}' AND magazine.registrationid = registration.registrationid AND company.companynumber = registration.companynumber");
Was genau soll dann dieser PHP-Code (siehe Zitat 1353?
Damit läufst Du höchstens Gefahr, dass man Dich auf die Gefahr von SQL-Injections aufgrund Deines offensichtlichen viel zu sorglosen Umgangs mit Benutzereingaben hinweist ...
Das Problem ist: Mein PC verarbeitet diese Anfrage nicht, obwohl sie korrekt formuliert zu sein scheint.
Es handelt sich um 3 Tabellen, von denen jede 500.000 Datensätze á ca. 7-10 Spalten hat.
Das an sich ist eigentlich kein Problem. Hast Du auf den Spalten, die Du als Filterkriterium bzw. "Foreign-Key" nutzt, vernünftige Indizes liegen (um die Suche zu beschleunigen)?
Prinzipiell würde ich Dir allerdings raten, die explizite JOIN-Syntax zu nutzen - das macht den SQL-Code IMHO erheblich lesbarer und einfacher verständlich.
RegistrationID und Companynr sind ganz normale Tabellenspalten, die nicht als Primärschlüssel definiert sind.
Außerdem würde ich Dir empfehlen, auf genau diese verwendeten Spalten jeweils einen Index zu legen.
MfG,
EKKi
Schon mal meinen ganz herzlichen Dank an alle.
Das mit den Indizes hat das ganze arg beschleunigt.
Nun funktionieren die Abfragen sogar ohne INNER JOIN in akzeptabler Geschwindigkeit.
INNER JOIN werde ich anwenden, wenn es mehrere Suchtreffer gibt.
Ansonsten beschränke ich es mit LIMIT 0, 1.
moin,
INNER JOIN werde ich anwenden, wenn es mehrere Suchtreffer gibt.
Ansonsten beschränke ich es mit LIMIT 0, 1.
vielleicht solltest du anfangen zu verstehen, warum dir INNER JOIN vorgeschlagen wird. dann würdest du wissen, dass das nichts, aber auch gar nichts mit der anzahl der datensätze in der ergebnismenge zu tun haat....
Ilja