Peter Schmidt: SQL-Abfrage optimieren

Moin!

Ich möchte eine mySQL Abfrage optimieren. Da ich von mysql nicht so viel ahnung habe frage ich mal hier da die abfrage relativ lange dauert.

Also erstmal meine aktuelle Abfrage:

SELECT
        villages.x,
        villages.y,
        tribe.name,
        ally.id

FROM
        (villages LEFT JOIN
                tribe ON villages.tribe=tribe.id) LEFT JOIN
                        ally ON tribe.ally=ally.id
        WHERE
                (villages.x >= ".$x_start.") && (villages.x <= ".$x_end.") &&
                (villages.y >= ".$y_start.") && (villages.y <= ".$y_end.");";

Ich denke die Verknüpfung ist eindeutig:
Es soll aus der Tabelle villages das tribe Feld mit der id aus tribe verknüpft werden. Außerdem soll aus der Tabelle tribe das Feld ally mit dem Feld id aus der Tabelle ally verknüpft werden. Es soll aber auch funktionieren wenn villages.tribe und tribe.ally nicht definiert sind.

  1. noch eine ergänzung: (hab außversehen auf absenden geklickt, wollte eigentlich ne vorschau anzeigen *g*)

    das ganze soll nur ausgegeben werden wenn villages.x und villages.y in einem Bestimmten Berreich liegt. Ich weiß nicht ob man das mit WHERE machen soll oder ob es anderes schneller geht. Ich glaube WHERE sortiert erst aus nachdem die tabellen verknüpft wurden oder? Ich denke, dass das verknüpfen aber am längsten dauert. Also gibt es eine möglichkeit diesen Bereich zu optimieren?

    Danke schonmal für eure Hilfe, Peter

    1. noch eine ergänzung: (hab außversehen auf absenden geklickt, wollte eigentlich ne vorschau anzeigen *g*)

      das ganze soll nur ausgegeben werden wenn villages.x und villages.y in einem Bestimmten Berreich liegt. Ich weiß nicht ob man das mit WHERE machen soll oder ob es anderes schneller geht. Ich glaube WHERE sortiert erst aus nachdem die tabellen verknüpft wurden oder? Ich denke, dass das verknüpfen aber am längsten dauert. Also gibt es eine möglichkeit diesen Bereich zu optimieren?

      Danke schonmal für eure Hilfe, Peter

      Hi,

      vielleicht tut dir das helfen (gilt für die SQL92-Syntax aus MS-SQL-Server 7 afaik):

      • distinct wenn es geht beim select benutzen
      • im join möglichst unterscheiden zw. left,right,inner
      • im join kannst du z.b. sagen:
        left join table2 on table1.index = table2.index

      eine ON-Verknüpfung ist schneller als eine WHERE-Verknüpfung aber wichtiger ist der strukturierte Aufbau der DB und die richtigkeit der Abfrage. Haste PrimaryKey und das Klump? Mit deinem Query kann ich dir leider nicht helfen, weil ich es nicht verstanden habe. Gehts einfacher (so einfach wie möglich)?

      mfg Kadir

        • distinct wenn es geht beim select benutzen

        kenn ich nicht :(

        • im join möglichst unterscheiden zw. left,right,inner
        • im join kannst du z.b. sagen:
          left join table2 on table1.index = table2.index

        das habe ich ja benuzt...

        eine ON-Verknüpfung ist schneller als eine WHERE-Verknüpfung aber wichtiger ist der strukturierte Aufbau der DB und die richtigkeit der Abfrage.

        Deswegen such ich nach einer alternative für WHERE

        Haste PrimaryKey und das Klump?

        hm guck ich nochmal nach. als primary muss man doch immer die ID felder definieren oder? und was ist Klump?

        Mit deinem Query kann ich dir leider nicht helfen, weil ich es nicht verstanden habe. Gehts einfacher (so einfach wie möglich)?

        hm. frag doch bitte nach. ist eigentlich alles drin was wichtig ist. wenn ich was rausnehme ist es nicht meher das was es vorher war...

        Danke schonmal, peter

          • distinct wenn es geht beim select benutzen

          kenn ich nicht :(

          Beispiel:

          spalte1
          *******
          a
          b
          c
          a
          v

          query:
          select distinct spalte1 from tabletest

          result:
          a
          b
          c
          v
          (doppelte wurden entfernt)

          • im join möglichst unterscheiden zw. left,right,inner
          • im join kannst du z.b. sagen:
            left join table2 on table1.index = table2.index

          das habe ich ja benuzt...

          SELECT
          villages.x,
          villages.y,
          tribe.name,
          ally.id

          FROM villages
          LEFT JOIN tribe ON villages.tribe=tribe.id
          LEFT JOIN ally ON tribe.ally=ally.id

          WHERE
          villages.x >= ".$x_start.")
          && (villages.x <= ".$x_end.")
          && (villages.y >= ".$y_start.")
          && (villages.y <= ".$y_end.")

          Da ich kein Query-Prog habe, ist es schwierig, das im Kopf zu analysieren. Am Besten ist, du baust deinen Code komplett neu auf. Ein Schritt nach dem Anderen. Dann wirst du sehen, warum es langsamer geworden ist. Hat bei mir auch immer funktioniert.

          eine ON-Verknüpfung ist schneller als eine WHERE-Verknüpfung aber wichtiger ist der strukturierte Aufbau der DB und die richtigkeit der Abfrage.

          Deswegen such ich nach einer alternative für WHERE

          Das hat aber mit der Struktierung der Abfrage zu tun, nur damit du es weisst.

          Haste PrimaryKey und das Klump?

          hm guck ich nochmal nach. als primary muss man doch immer die ID felder definieren oder? und was ist Klump?

          :) Klump ist auf österreichisch Müll. Primary Key ist die Indexspalte. Entweder ein Zähler oder ein "eindeutiger Identifizierer". Möglichst Zahl und richtig definieren (Geschwindigkeit).

          Mit deinem Query kann ich dir leider nicht helfen, weil ich es nicht verstanden habe. Gehts einfacher (so einfach wie möglich)?

          hm. frag doch bitte nach. ist eigentlich alles drin was wichtig ist. wenn ich was rausnehme ist es nicht meher das was es vorher war...

          Danke schonmal, peter

          Wie gesagt, bau es neu zusammen is am Besten. Ich hatte Abfragen, die waren najo ziemlich gross da verliert man leicht die Übersicht.

          1. Beispiel:

            spalte1
            *******
            a
            b
            c
            a
            v

            query:
            select distinct spalte1 from tabletest

            result:
            a
            b
            c
            v
            (doppelte wurden entfernt)

            das bring bei mir leider nix. ich habe keinen doppelten einträge....

            eine ON-Verknüpfung ist schneller als eine WHERE-Verknüpfung aber wichtiger ist der strukturierte Aufbau der DB und die richtigkeit der Abfrage.

            Deswegen such ich nach einer alternative für WHERE

            Das hat aber mit der Struktierung der Abfrage zu tun, nur damit du es weisst.

            Haste PrimaryKey und das Klump?

            hm guck ich nochmal nach. als primary muss man doch immer die ID felder definieren oder? und was ist Klump?

            :) Klump ist auf österreichisch Müll. Primary Key ist die Indexspalte. Entweder ein Zähler oder ein "eindeutiger Identifizierer". Möglichst Zahl und richtig definieren (Geschwindigkeit).

            und was soll ich mit dem Müll machen??? also die Primary Keys habe ich richtig gesetzt

            Wie gesagt, bau es neu zusammen is am Besten. Ich hatte Abfragen, die waren najo ziemlich gross da verliert man leicht die Übersicht.

            naja die übersicht habe ich noch ;) es muss alles rein was bisher drin ist.. ich frage mich nur ob es einen anderen weg gibt...

            mfg, Peter