mysqlfan: Ist mein Rechner für tabellenübergreifende SQL-Abfrage zu lahm?

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.

  1. indizes?

    --
    for your security, this text has been encrypted by ROT13 twice.
  2. 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

  3. 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

  4. 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

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
  5. 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.

    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