Announcement

Collapse
No announcement yet.

Langsames Statement

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Langsames Statement

    Hallo,

    ich habe in einer anwendung viele statistische Abfragen, die all auch schnell beantortet werden. Bis auf eine :
    Tabellen Rechnung, Teile und Artikel.
    In Artikel stehen Artikelnummer und Warengruppe.
    In Teile Artikelnummer,Anzahl.
    In Rechnung Datum,Nachlässe.

    Ich brauche ein Ergebnis alle verkauften Teile zwischen 2 Verkaufsdatum einer bestimmten Warengruppe.

    Die Abfrage :

    <PRE>
    select t.einzel,t.anzahl,t.artnummer,a.wg,a.text,a.netto, r.gedruckt,r.datum,
    r.n1,r.n2,r.n3,r.n4,r.nachlass1,r.nachlass2,r.nach lass3,r.nachlass4,
    r.vknummer
    from teile t, rechnung r, artikel A
    where r.gedruckt = 'J'
    and a.wg = :WGruppe
    and r.datum >= :Start
    and r.datum <= :Ende
    and t.vknummer = r.vknummer
    and a.artnummer = t.artnummer
    and t.einzel > 0
    and t.anzahl > 0
    and a.netto > 0
    order by a.text
    </PRE>

    ist bei 10000 Rechnungen und 50000 Teilezeilen 10 Minuten unterwegs. Ähnliche Abfragen sind nach Sekunden fertig.

    Weiß jemend, wo ich den Gedankenfehler habe ?

    Gruß Günter

  • #2
    Hallo Günter,

    warum verwendest Du eigentlich keine Joins für die Verbindung der Tabellen Teile, Rechnung und Artikel? Das könnte eventuell schon helfen.

    Daneben schau Dir mal die Zugriffsstatistiken dieser Abfrage an (z.B. mit IBExpert). Daran siehst Du welche Indices verwendet werden und wieviel Zugriffe auf die einzeln Tabellen erfolgen. Damit kann man sich dann auf die Problemsuche begeben.

    Der Interbase Optimizer hat bekanntlich so seine Schwächen (gilt auch für Firebird) auch wenn sich das von Version zu Version etwas bessert.

    Tschau

    Torste

    Comment


    • #3
      Hallo Günter,<br><br>
      als erstes würde ich die Tabellen in der Reihenfolge<br><br>
      from rechnung r, teile t, artikel A<br><br>
      angeben. Man soll immer die kleinste Tabelle als MasterTabelle (erst genannte) angeben. Diese kleine Änderung macht schon ne Menge aus. Und das Order By a.text... würd ich mal weg lassen. Ich kann mir nicht vorstellen das es über den text einen Index gibt.<br><br>
      @Torsten<br>
      die Auflistung "from teile t, rechnung r, artikel A " wird von SQL wie <br><br>
      from teile t<br>
      inner join rechnung r<br>
      inner join artikel a<br><br>
      interpretiert. Das erklärt auch warum zuerst die kleinste Tabelle stehen sollte (siehe oben). Günter könnte auch ein "left outer join" Anwendend, die sind aber in der Regel noch langsamer.
      <br><br>
      Gruß Fran

      Comment


      • #4
        Hallo,

        ich hatte alle kombinationen versucht, where, join, diverse outer join, plan etc.

        das schnellste Konstrukt sieht folgendermaßen aus :

        <pre>
        select r.datum, t.artnummer ,t.anzahl, t.einzel, a.wg, a.Text, w.text
        from Teile T
        join artikel a on t.artnummer = a.artnummer
        join wg w on a.wg = w.wg
        join Kunden k on k.vernummer = arvertreter
        join rechnung r on r.edvnummer = k.edvnummer
        where r.datum >= :Parstart
        and r.datum <= :ParEnde
        </pre>

        Warengruppe 20, Artikel 500

        Ich wollte aus der Nachschlagetabelle wg den Warengruppentext. Fatal.
        Ohne diese Tabelle dauert die Abfrage ca. 3 Sek. Mit dieser Tabelle
        ca 15 Minuten.

        Ich kann jetzt die Abfrage ohne Warengruppe in ein Grid einlesen und den Warengruppentext nachfüllen. Ich finde, das ist jedoch kein schöne Lösung. Was kann an der tabelle falsch sein ? Es gibt für alle Wertekombinationen Indizes. Hier ist das Ergbnis vom PLAN :

        <pre>
        PLAN JOIN (A NATURAL,W INDEX (RDB$PRIMARY1),K INDEX (VERNUMMER_X),R INDEX (RECHEDVNUMMER_X,DATUMX),T INDEX (TEILART_X))
        </pre>

        Hier finde ich nichts falsch, oder ?

        Gruß Günte

        Comment


        • #5
          Hallo Günter,

          Dein Problem liegt eindeutig in der Artikeltabelle. Bei der Abfrage wird dieser Tabelle wird kein Index verwendet. De Zugriffsstatistik für die Tabelle Artikel wird sehr wahrscheinlich grauenhaft aussehen (zig Millionen Zugriffe).

          In Deinem letzten SQL hast Du keine Verknüfung zwischen "t" und "r".

          Die Tabelle "Teile" ist so auf den ersten Blick als Ausgangstabelle völlig ungeeignet. Ich würde entweder Rechnung oder Kunden als Ausgangstabelle verwenden (select ... from Ausgangstabelle). Die Ausgangstabelle wird dann in der where-Klausel entsprechend eingeschränkt.

          Du kannst mir ja mal die Datenbank zum testen schicken (aber nur wenn's auch wirklich eine Interbase/Firebird-Datenbank ist [email protected]).

          Tschau

          Torste

          Comment


          • #6
            Hallo Torsten,

            ich habe alle Kombinationen (25) probiert, um sinnvolle Reihenfolgen zu bekommen.
            Soweit ich A.Kosch verstanden habe, heist 'natural', das die Tabelle in den Speicher eingelesen wird, damit Sie schneller abgearbeitet werden kann.
            Ist ja auch sinnvoll, da die Artikeltabelle nach Warengruppe und nach Artikelnummer durchsucht wird. (Warengruppe, um aus der Nachschlagtabelle den Warengruppentext zu ermitteln, Artikelnummer, um den zum Verkaufs-Teil gehörigen Artikeltext auszulesen).

            Da ich keine Dummydaten haben, sondern mit Kopien der Kundendaten arbeite, um die Perfomance zu testen, kann ich die 50MB nicht verschicken. Mit einer leeren Bank ist ja nichts getan. Oder kannst Du etwas mit den Metadaten anfangen ?

            Gruß Günte

            Comment


            • #7
              Hallo Günter,

              mit den Metadaten ist es zwar etwas mühsam, aber dann generiere ich mir halt ein paar Testdaten und dann schau wir mal weiter.

              Die Reihenfolge kann schon erhebliche Auswirkungen haben. Natural heißt halt das kein Index verwendet wird, sagt aber nicht aus wie oft die Tabelle gescannt wird. Auf Arbeit hatten wir vor kurzem einen ähnliches Problem. Es wurden mehrere ineinander verschachtelte StoredProc's aufgerufen. Laufzeit war deutlich über eine Stunde.
              Nach einer winzigen Änderung bin ich dann auf etwa 15 Sekunden Laufzeit runtergekommen. Die Anzahl der Fetches hatte sich von ca. 600 Mio. auf etwa 200000 reduziert.

              Tschüß

              Torste

              Comment

              Working...
              X