Karlo: JOIN dauert mehrere Minuten (Problem: fehlende FKs ?)

Hallo,

hab folgende Datenbankstruktur:
Tabelle ORT:
id(PK), value, key

Tabelle NAME:
id(PK), value, key

Tabelle KEYS:
key(PK)

Jede der Tabellen beinhaltet knapp 2 Millionen Datensätze. Datenbank ist MySQL, Engine ist MyISAM. Anscheinend gibt es für MyISAM keine Fremdschlüsselbeziehungen, oder seh ich das falsch?

Problem ist, dass ein JOIN zweier Tabellen sehr lange dauert:
SELECT *
FROM ORT,NAME
WHERE ORT.key = NAME.key AND NAME.value = 'Mustermann'

Das dauert mehrere Minuten, sollte aber IMHO in Sekunden machbar sein. Was mache ich falsch?

  1. Moin!

    Das dauert mehrere Minuten, sollte aber IMHO in Sekunden machbar sein. Was mache ich falsch?

    Lass es dir von der DB erklären: EXPLAIN. Das listet dir auf, welche Indices verwendet werden, und was sonst so passiert.

    - Sven Rautenberg

    1. Lass es dir von der DB erklären: EXPLAIN. Das listet dir auf, welche Indices verwendet werden, und was sonst so passiert.

      Wenn ich folgenden Befehl ausführe:
      EXPLAIN SELECT *
      FROM ort, name
      WHERE ort.key = name.key
      AND name.value = 'Mustermann';

      dann führt das zu folgender Ausgabe:
      id select_type table type possible_keys key key_len ref rows Extra
      1 SIMPLE ort ALL fk_ort_keys NULL NULL NULL 2907694
      1 SIMPLE name ref fk_name_keys fk_name_keys 38 testdb.ort.key 10 Using where

      Allerdings werde ich daraus auch nicht schlau. Kann mir jemand das erklären?
      Sollte ich vielleicht noch die Tabelle KEYS in die Abfrage mit einbinden?

      1. Moin!

        Wenn ich folgenden Befehl ausführe:

        Sehr gut!

        EXPLAIN SELECT *
        FROM ort, name
        WHERE ort.key = name.key
        AND name.value = 'Mustermann';

        dann führt das zu folgender Ausgabe:
        id   select_type   table   type  possible_keys   key           key_len   ref             rows     Extra
        1    SIMPLE        ort     ALL   fk_ort_keys     NULL          NULL      NULL           2907694
        1    SIMPLE        name    ref   fk_name_keys    fk_name_keys  38        testdb.ort.key  10      Using where

        Allerdings werde ich daraus auch nicht schlau. Kann mir jemand das erklären?

        Das Handbuch bietet folgende Seite: http://dev.mysql.com/doc/refman/5.1/de/explain.html

        Was sehen wir also? Die erste Zeile zeigt an, was aus der Tabelle "ort" an Indices benutzt werden kann. Wir sehen: type = ALL, und die Handbuchseite sagt dazu: "ganz schlimm", weil das ein Full-Table-Scan ist. Hier verschenkst du also mächtig Performance.

        Das Problem, Ilja hat es schon angesprochen, ist unter anderem deine Schreibweise des Joins. Ändere das. Das erleichtern der Datenbank und auch dir dann, die Zusammenhänge zwischen "Bedingung zur Zuordnung des Joins" zu trennen von "Bedingung zur Aussiebung der gewünschten Daten".

        Zweitens: Du hast die Verknüpfung der beiden Tabellen "ort" und "name" über die jeweilige Spalte "key". Das schreit förmlich danach, diese Spalte als Index anzulegen. Die Frage ist, ob die Spalte schon in irgendeiner Tabelle ein Index (z.B. primärer Index) ist. Wenn ja, dann wäre die andere Spalte noch als einfacher Index hinzuzufügen, wobei darauf zu achten ist, dass die Datentypen der beiden Tabellen identisch ist. Also nicht einmal BIGINT, einmal TINYINT nehmen, sondern das Gleiche! Im Zweifel den Datentyp mit dem größeren Wertebereich.

        Irgendwelche Indices hast du offenbar schon angelegt, sonst würde in der Spalte "possible_keys" nicht "fk_ort_keys" und "fk_name_keys" erscheinen. Die Frage wäre, was das für Indices sein sollen. Vermutlich sind sie derzeit einfach überflüssig, zumindest fk_ort_keys, aber das hängt von den anderen Abfragen ab, die du sonst noch so ausführst.

        Sollte ich vielleicht noch die Tabelle KEYS in die Abfrage mit einbinden?

        Diese Tabelle taucht in deiner Abfrage bislang absolut nicht auf, also warum sollte sie hinzugefügt werden?

        - Sven Rautenberg

        1. Hallo Sven,

          vielen Dank für deine ausführliche Antwort. Bin momentan nicht zu Hause und kann mir daher erst heute Abend deine Erklärung genauer anschsehen.

          Irgendwelche Indices hast du offenbar schon angelegt, sonst würde in der Spalte "possible_keys" nicht "fk_ort_keys" und "fk_name_keys" erscheinen. Die Frage wäre, was das für Indices sein sollen. Vermutlich sind sie derzeit einfach überflüssig, zumindest fk_ort_keys, aber das hängt von den anderen Abfragen ab, die du sonst noch so ausführst.

          Hier allerdings mal die Grafik des zu Grunde liegenden DB Schemas:

          Die Tabellen ort und name haben key als Fremdschlüssel, der sich auf key der Tabelle keys bezieht. Die keys sind von Typ VARCHAR(8) weil der key aus Zeichen und Ziffern besteht.

          Hoffe das hilft dir weiter :-/

          1. yo,

            Die Tabellen ort und name haben key als Fremdschlüssel, der sich auf key der Tabelle keys bezieht. Die keys sind von Typ VARCHAR(8) weil der key aus Zeichen und Ziffern besteht.

            ich hatte ja bereits in meinen ersten post die frage gestellt, aber hier gerne noch einmal. was ist der sinn der tabelle keys und warum nimmst du keinen künstlichen schlüssel ?

            Ilja

            1. Hey,

              ich hatte ja bereits in meinen ersten post die frage gestellt, aber hier gerne noch einmal. was ist der sinn der tabelle keys und warum nimmst du keinen künstlichen schlüssel ?

              Ich hoffe ich versteh dich richtig: Klar kann ich einen künstlichen Schlüssel wie bspw. nen integer nehmen aber dann geht mir die Beziehung zu den bereits vorgegebenen, existierenden keys verloren.

              1. yo,

                Klar kann ich einen künstlichen Schlüssel wie bspw. nen integer nehmen aber dann geht mir die Beziehung zu den bereits vorgegebenen, existierenden keys verloren.

                nicht wirklich, wenn du erst mal in der tabelle einen künstlichen schlüssel hinzugefügt hast, kannst du bei den tabellen auf die du referenzierst die fremdschlüsel entsprechend mit einem update anpassen. das problem ist also lösbar und am ende hast du dann deinen künstlichen schlüssel.

                Ilja

                1. nicht wirklich, wenn du erst mal in der tabelle einen künstlichen schlüssel hinzugefügt hast, kannst du bei den tabellen auf die du referenzierst die fremdschlüsel entsprechend mit einem update anpassen. das problem ist also lösbar und am ende hast du dann deinen künstlichen schlüssel.

                  Seh ich das richtig wenn ich sage du meinst folgendes:

                  Tabelle keys
                  id    key
                  1     000AFB
                  2     0001E1

                  Tabelle ort
                  id   value   fk_id
                  1    Berlin  2

                  1. yo,

                    Seh ich das richtig...

                    genau....

                    Ilja

                    1. yo,

                      »» Seh ich das richtig...

                      genau....

                      Ilja

                      Gut aber löst das meine Performance-Probleme? Nur wegen dem Switch von String auf int? Oder ist zusätzlich noch eine Konvertierung auf die InnoDB Engine erforderlich?

                      1. yo,

                        Gut aber löst das meine Performance-Probleme? Nur wegen dem Switch von String auf int? Oder ist zusätzlich noch eine Konvertierung auf die InnoDB Engine erforderlich?

                        dazu hatte ich dir ja auch schon einiges geschrieben. deine performance-probleme werden weniger auf der Engine beruhen, fremdschlüssel gibt es bei jeder engine und version von mysql. in der tabelle name einen zusammengesetzten index über die spalten key und value und in der tabelle ort einen über die key spalten, bzw. wenn du dann die fremdschlüssel ändert die entsprechenden spalten. und wie grsagt, name und keys sind nicht wirklich treffende bezeichner für die tabellen.

                        Ilja

                        1. in der tabelle name einen zusammengesetzten index über die spalten key und value und in der tabelle ort einen über die key spalten, bzw. wenn du dann die fremdschlüssel ändert die entsprechenden spalten.

                          Da komme ich nicht mit.
                          Du denkst ich soll einen zusammengesetzten Schlüssel über value und key machen? Was bringt mir das? Ich will doch als Fremdschlüssel auf den Primärschlüssel in der Tabelle keys referenzieren.

                          1. yo,

                            Du denkst ich soll einen zusammengesetzten Schlüssel über value und key machen? Was bringt mir das? Ich will doch als Fremdschlüssel auf den Primärschlüssel in der Tabelle keys referenzieren.

                            zum einen würde ich es erst einmal umsetzen und dann schauen, was passiert. zum anderen muss das dbms ja in allen beteiligten tabellen bei einem JOIN nach den passenden werten suchen. somit reicht es nicht aus, nur in einer tabelle zu sortieren (index).

                            Ilja

                            1. zum einen würde ich es erst einmal umsetzen und dann schauen, was passiert. zum anderen muss das dbms ja in allen beteiligten tabellen bei einem JOIN nach den passenden werten suchen. somit reicht es nicht aus, nur in einer tabelle zu sortieren (index).

                              Tut mir leid, verstehe immer noch nur Bahnhof.

                              Kannst du mal folgende Tabellen so umbauen/ergänzen, wie du es meinst (kannst auch die Spaltennamen verändern):

                              Tabelle
                              keys
                              id   key

                              Tabelle
                              ort
                              id   value   key

                              1. yo,

                                Tut mir leid, verstehe immer noch nur Bahnhof.

                                nicht dass der zug schon abgefahren ist...spass beseite, ich beziehe mich mal auf deine ausgangsabfrage, also ganz ohne die besprochenen anderen änderungen.

                                SELECT *
                                FROM ORT,NAME
                                WHERE ORT.key = NAME.key AND NAME.value = 'Mustermann'
                                ;

                                bei dieser abfrage hast du ja massive performance probleme. mein tipp. lege doch mal einen index in der tabelle "ort" über die spalte "key" an. und in der tabelle "name" einen zusammengesetzten index (ein index, der über zwei spalten geht) über die spalten value und key in der reihenfolge.

                                oder mit anderen worten, erst einmal nichts an den tabellen ändern, sondern nur zwei nidexe erstellen und dann die abfrage noch einmal probieren.

                                Ilja

                                1. nicht dass der zug schon abgefahren ist...spass beseite, ich beziehe mich mal auf deine ausgangsabfrage, also ganz ohne die besprochenen anderen änderungen.

                                  Nene, ich bin ja wirklich dankbar für jede Hilfe =)

                                  Ich werds hoffentlich heute abend probieren falls ich noch rechtzeitig nach Hause komme =)
                                  Ich sag dir Bescheid!

          2. Moin!

            »» Irgendwelche Indices hast du offenbar schon angelegt, sonst würde in der Spalte "possible_keys" nicht "fk_ort_keys" und "fk_name_keys" erscheinen. Die Frage wäre, was das für Indices sein sollen. Vermutlich sind sie derzeit einfach überflüssig, zumindest fk_ort_keys, aber das hängt von den anderen Abfragen ab, die du sonst noch so ausführst.

            Hier allerdings mal die Grafik des zu Grunde liegenden DB Schemas:

            Uii, eklig. Die Tabelle "keys" hat überhaupt keinen nachvollziehbaren Existenzgrund. Deshalb ist sie in deinem Join auch nicht enthalten, weil man sie schlicht nicht benötigt. Sie speichert ausschließlich redundante Informationen.

            Die Tabellen ort und name haben key als Fremdschlüssel, der sich auf key der Tabelle keys bezieht. Die keys sind von Typ VARCHAR(8) weil der key aus Zeichen und Ziffern besteht.

            Wie sind die Fremdschlüssel denn realisiert? Am besten, du postest mal das CREATE-Statement der drei Tabellen. Außerdem wären ein, zwei Demo-Datensätze, die darin gespeichert sind, nicht schlecht, so zur Anschauung.

            Die Kritik von Ilja an dem Datenformat der keys bzw. deren Verwendungszweck kann ich nachvollziehen, aber nur teilweise. Tabellenverknüpfung über Schlüssel ist am performantesten, wenn man einen vernünftig indizierbaren, eindeutigen Inhalt mit möglichst kleiner Datenmenge hat. Der Klassiker ist halt ein INTEGER-Feld, das ist eindeutig hochzählbar und braucht 32 Bit = 4 Byte - sehr datensparsam und effizient. Ein VARCHAR(8) benötigt, je nach gewählter Kollation, schon mal mindestens 8, wenn nicht bis zu 24 Byte. Es ist zwar indizierbar, aber mindestens mit gefühlten Bauchschmerzen. Außerdem deutet sich durch die Mischung von Buchstaben und Zahlen irgendwie an, dass dieser Key mehr ist als nur irgendein Identifikator, er hat vermutlich auch noch irgendeine inhaltliche Bedeutung. Das mag man als DB-Designer noch weniger.

            Allerdings: Man kann damit leben, solange die Indizierung existiert, funktioniert und die JOINs schnell sind - was aktuell ja das Problem darstellt. :)

            - Sven Rautenberg

            1. Wie sind die Fremdschlüssel denn realisiert? Am besten, du postest mal das CREATE-Statement der drei Tabellen. Außerdem wären ein, zwei Demo-Datensätze, die darin gespeichert sind, nicht schlecht, so zur Anschauung.

              Ok hier das Create Statement:

              SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;  
              SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_keyCHECKS, FOREIGN_KEY_CmydbHECKS=0;  
              SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';  
                
              CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;  
              USE `mydb`;  
                
              -- -----------------------------------------------------  
              -- Table `mydb`.`keys`  
              -- -----------------------------------------------------  
              CREATE  TABLE IF NOT EXISTS `mydb`.`keys` (  
                `key` VARCHAR(12) NOT NULL ,  
                PRIMARY KEY (`key`) )  
              ENGINE = MyISAM;  
                
                
              -- -----------------------------------------------------  
              -- Table `mydb`.`name`  
              -- -----------------------------------------------------  
              CREATE  TABLE IF NOT EXISTS `mydb`.`name` (  
                `id` INT NOT NULL AUTO_INCREMENT ,  
                `value` VARCHAR(300) NOT NULL ,  
                `key` VARCHAR(12) NOT NULL ,  
                INDEX `fk_name_keys` (`key` ASC) ,  
                PRIMARY KEY (`id`) ,  
                CONSTRAINT `fk_name_keys`  
                  FOREIGN KEY (`key` )  
                  REFERENCES `mydb`.`keys` (`key` )  
                  ON DELETE NO ACTION  
                  ON UPDATE NO ACTION)  
              ENGINE = MyISAM;  
                
                
              -- -----------------------------------------------------  
              -- Table `mydb`.`ort`  
              -- -----------------------------------------------------  
              CREATE  TABLE IF NOT EXISTS `mydb`.`ort` (  
                `id` INT NOT NULL AUTO_INCREMENT ,  
                `value` VARCHAR(12) NOT NULL ,  
                `key` VARCHAR(12) NOT NULL ,  
                INDEX `fk_ort_keys` (`key` ASC) ,  
                PRIMARY KEY (`id`) ,  
                CONSTRAINT `fk_ort_keys`  
                  FOREIGN KEY (`key` )  
                  REFERENCES `mydb`.`keys` (`key` )  
                  ON DELETE NO ACTION  
                  ON UPDATE NO ACTION)  
              ENGINE = MyISAM;  
                
                
              -- -----------------------------------------------------  
              -- Table `mydb`.`identity_relation`  
              -- -----------------------------------------------------  
              CREATE  TABLE IF NOT EXISTS `mydb`.`identity_relation` (  
                `id` INT NOT NULL AUTO_INCREMENT ,  
                `value` VARCHAR(300) NOT NULL ,  
                `key` VARCHAR(12) NULL ,  
                INDEX `fk_identity_relation_keys` (`key` ASC) ,  
                PRIMARY KEY (`id`) ,  
                CONSTRAINT `fk_identity_relation_keys`  
                  FOREIGN KEY (`key` )  
                  REFERENCES `mydb`.`keys` (`key` )  
                  ON DELETE NO ACTION  
                  ON UPDATE NO ACTION)  
              ENGINE = MyISAM;
              

              Demodatensätze:

              Tabelle keys:
              keys
              0001AF
              000F19
              001B9E

              Tabelle name:
              id        value        key
              1         Mustermann   0001AF
              2         Huber        000F19
              3         Huber jun.   000F19
              4         Meier        001B9E

              Tabelle ort:
              id        value        key
              1         Hamburg      0001AF
              2         Berlin       000F19
              3         Berlin       000F19
              4         Dresden      001B9E

              Die Tabelle keys hab ich deswegen angelegt, um eine Tabelle zu haben, die alle keys genau einmal enthält.

              1. yo,

                Die Tabelle keys hab ich deswegen angelegt, um eine Tabelle zu haben, die alle keys genau einmal enthält.

                die scripts sind zwar gut zu kennen, aber ohne deine fachlichkeit zu kennen, was genau du abbilden willst, hilft es uns mal gar nichts. wie bereits erwähnt, halte ich nicht viel von sprechenden schlüsseln (tabelle keys) und würde grundsätzlich davon abraten. des weiteren scheint ein design fehler vorzuliegen, wenn in der tabelle Ort einträge mehrmals für einem ort vorkommen (berlin). aber um genau das zu klären, müssen wir deine fachlichkeiten kennen. desweiteren halte ich den namen einer tabelle keys und name für wenig geeignet, sagt zuwenig über den inhalt aus.

                Ilja

              2. Moin!

                Ok hier das Create Statement:

                Daran ist schon einiges zu kritisieren.

                Allen voran: Du willst zwar Konstrukte wie Foreign Keys verwenden, aber das gelingt dir nicht, weil du MyISAM als Storage-Engine benutzt. MyISAM ist schnell, aber unterstützt viele Features nicht, die man gelegentlich haben will - darunter sowas wie Transaktionen, Trigger, Foreign Keys, Stored Procedures etc. Neben etlichen anderen Storage Engines bietet InnoDB diese Features an.

                Aufgrund der falschen Storage Engine ist die Tabelle keys in deinem jetzigen Modell absolut funktionslos, und damit sinnlos. Abgesehen davon würde man sie vermutlich auch sonst nicht so realisieren.

                Die alles entscheidende Frage ist: Woher kommen diese Keys, und was soll damit gemacht werden?

                Tabelle keys:
                keys
                0001AF
                000F19
                001B9E

                Vernünftig wäre, die Keys an dieser Stelle einer künstlichen ID zuzuordnen, die numerisch ist, und die überall sonst ausschließlich für die Zuordnung von Datensätzen zum Key genutzt wird.

                Im übrigen sieht es so aus, als handele es sich hier um hexadezimale Zahlen. Die würde ich sowieso nie als String abspeichern, sondern immer als passenden INTEGER-Wert - je nach Wertebereich ggf. auch BIGINT, unsigned und ggf. mit passendem ZEROFILL.

                Tabelle name:
                id        value        key
                1         Mustermann   0001AF
                2         Huber        000F19
                3         Huber jun.   000F19
                4         Meier        001B9E

                Tabelle ort:
                id        value        key
                1         Hamburg      0001AF
                2         Berlin       000F19
                3         Berlin       000F19
                4         Dresden      001B9E

                Warum ist 000F19 doppelt in beiden Tabellen?

                Die Tabelle keys hab ich deswegen angelegt, um eine Tabelle zu haben, die alle keys genau einmal enthält.

                Mangels der Funktion der Foreign Keys in MyISAM bringt dir das exakt garnichts zur Zeit.

                - Sven Rautenberg

                1. echo $begrüßung;

                  MyISAM ist schnell, aber unterstützt viele Features nicht, die man gelegentlich haben will - darunter sowas wie Transaktionen, Trigger, Foreign Keys, Stored Procedures etc.

                  MyISAM kennt seit MySQL 5.0 Trigger und Stored Procedures und auch Views und Cursors.

                  echo "$verabschiedung $name";

                2. yo,

                  Aufgrund der falschen Storage Engine ist die Tabelle keys in deinem jetzigen Modell absolut funktionslos, und damit sinnlos. Abgesehen davon würde man sie vermutlich auch sonst nicht so realisieren.

                  das ist zu pauschal und kann ohne die genauen hintergründe zu kennen nicht getroffen werden. tabellen nur mit einem PK schlüssel können je nach bedarf schon auch sinn machen und zwar nicht nur wegen der referentiellen integrität. das hängt aber wie gesagt von seiner fachlichkeit ab.

                  Im übrigen sieht es so aus, als handele es sich hier um hexadezimale Zahlen. Die würde ich sowieso nie als String abspeichern, sondern immer als passenden INTEGER-Wert - je nach Wertebereich ggf. auch BIGINT, unsigned und ggf. mit passendem ZEROFILL.

                  die diskusion um den datentyp hatten wir hier im forum schon mal vor einiger zeit. ob ich INTEGER oder VARCHAR nehme hängt weniger von den inhalten ab, sondern primär von den prozessen, sprich will ich mit den daten rechnen, sortieren oder sonstiges tun, wo ich zahlen benötige. wenn dem aber nicht so ist, kann man sie ruhig als VARCHAR speichern. also gilt auch hier, man muss wissen, was genau er damit machen will.

                  Warum ist 000F19 doppelt in beiden Tabellen?

                  warum solte sie dort nicht doppelt vorkommen, schließlich ist es ja so eine art fremdschlüssel, der grundsätzlich mehrfach vorkommen kann ?

                  Mangels der Funktion der Foreign Keys in MyISAM bringt dir das exakt garnichts zur Zeit.

                  sie weiter oben, diese aussage sollte man so pauschal ohne die hintergründe zu kennen nicht treffen, eher vermuten.

                  Ilja

                3. Hi,

                  vielen Dank für die Rückmeldung!
                  Ich versuche das mal der Reihe nach abzuarbeiten:

                  Allen voran: Du willst zwar Konstrukte wie Foreign Keys verwenden, aber das gelingt dir nicht, weil du MyISAM als Storage-Engine benutzt. MyISAM ist schnell, aber unterstützt viele Features nicht, die man gelegentlich haben will - darunter sowas wie Transaktionen, Trigger, Foreign Keys, Stored Procedures etc. Neben etlichen anderen Storage Engines bietet InnoDB diese Features an.

                  Genau das war der Vater des Gedankens. Ich würde gerne Foreign Keys verwenden, daher auch das Design.
                  Grund: Die mögliche 1:n Beziehung zwischen einem key und einem namem bzw. ort. D.h. jeder key ist einmalig aber es ist möglich dass zu einem key mehrere Orte oder mehrere Namen existieren.
                  Zudem bietet die keys Tabelle noch die Möglichkeit zukünftig 1:1 Beziehungen in Form einer weiteren Spalte einzufügen.

                  Die alles entscheidende Frage ist: Woher kommen diese Keys, und was soll damit gemacht werden?

                  Das sind bereits existierende keys an denen ich auch nichts ändern kann. Einzig ein Mapping auf einen Integer wie von dir vorgeschlagen wäre möglich.

                  Im übrigen sieht es so aus, als handele es sich hier um hexadezimale Zahlen. Die würde ich sowieso nie als String abspeichern, sondern immer als passenden INTEGER-Wert - je nach Wertebereich ggf. auch BIGINT, unsigned und ggf. mit passendem ZEROFILL.

                  Stimmt, das sind hexadezimale Zahlen.

                  Warum ist 000F19 doppelt in beiden Tabellen?

                  Damit wollte ich zeigen, dass eine 1:n Beziehung theoretisch möglich ist.

                  Mangels der Funktion der Foreign Keys in MyISAM bringt dir das exakt garnichts zur Zeit.

                  Ok :-/

                  Meine Ideen wären jetzt:
                  1. Eine zusätzliche Mapping-Tabelle einführen die eine Zuordnung INT -> key vornimmt
                  2. Ändern der DB Engine auf InnoDB um mit Fremdschlüsseln arbeiten zu können. Hierbei stellt sich allerdings das Problem, dass das wahrscheinlich nicht so einfach möglich ist, da die Fremdschlüsselbeziehung ja irgendwie abgebildet werden muss.

  2. yo,

    Tabelle KEYS:
    key(PK)

    was ist den der sinn dieser tabelle ?

    Anscheinend gibt es für MyISAM keine

    Fremdschlüsselbeziehungen, oder seh ich das falsch?

    das siehst du falsch, MyISAM tabellen können nicht die referentiele Integrität sicherstellen, aber fremdschlüssel braucht jedes rdbms. und selbst wenn die MyIsam engine das köntte, hat das wenig mit deinem problem zu tnu.

    SELECT *
    FROM ORT,NAME
    WHERE ORT.key = NAME.key AND NAME.value = 'Mustermann'

    zum einen benutzt du die implizite schreibweise von joins. das hat zwar wenig mit der ausführungsgeschwindigkeit zu tnu, ließt sich aber nicht besonders gut. auch schreibt man tabellennamen in aller regel klein. besser wäre:

    SELECT *
    FROM name n
    INNER JOIN ort o ON o.key = n.key
    WHERE n.value = 'Mustermann'
    ;

    zum anderen fehlen dir wohl geeignete indexe. ein guter kandidat dafür wäre zum beispiel ein zusammengesetzter index der tabelle name über die spalten key und value. des weiteren in der tabelle ort die spalte key.

    Ilja