Announcement

Collapse
No announcement yet.

Langsame Abfrage

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

  • Langsame Abfrage

    Hallo beisammen,

    ich brauche einmal eure Hilfe!

    In einer Datenbank werden Informationen zu Verkäufen und den Kunden gespeichert.
    Aus diesen Informationen soll über einen selektierbaren Zeitraum der Umsatz, kundenbezogen, dargestellt werden.

    Dafür habe ich folgende SQl abgesetzt:
    Select V.ID, V.FID, V.Datum, V.Storno, VD.Verkaeufer, K.Name, sum(VD.Preis)
    from Verkaeufe V, Verkaufsdetails VD, Kunde k
    where (VD.VKID = V.ID) and ((K.ID = VD.Verkaeufer) or (k.id is NULL)) and (Datum >= :d1) and (Datum <= :d2) and (VD.Verkaeufer like :VKID)
    group by V.ID, V.FID, V.Datum, V.Storno, VD.Verkaeufer, K.Name
    order by V.Datum, V.ID


    Je nach Zeitraum ist diese Abfrage aber quälend langsam. In der Detailtabelle sind ca. 14500 Vorgänge gespeichert. Da sollte die Abfrage doch noch recht hurtig gehen.

    Was könnte ich verbessern?
    Der Zugriff erfolgt lokal, über Interbase oder Firebird oder FB embedded.

    Vielen Dank für eure Hilfe

    Gruß

    Peter

  • #2
    Hallo!

    Ich kenn mich zwar mit Interbase nicht wirklich aus, aber ich denke, wenn du in deinem SQL Statement mit JOIN's arbeitest (sofern Interbase diese unterstuetzt), koenntest du sicherlich einiges an Speed herausholen.

    Beispiel:
    SELECT ... FROM Verkaeufe V LEFT JOIN Verkaufsdetails VD ON v.PK = VD.FK INNER JOIN Kunde K ON V.Kunde = K.Kunde WHERE ...

    Vielleicht bringt's was.
    *-- robert.oh. --*

    Comment


    • #3
      Hallo Robert,

      vielen Dank für deine Antwort.
      Join wird unterstützt. Ich habe aber den Eindruck, dass Abfragen mit where schneller laufen als mit join.

      Ist da wirklich eine Unterschied ausser in der Syntax?

      Gruß

      Peter

      Comment


      • #4
        Hallo Peter!

        Soweit ich weiss, macht ein SQL Statement ohne JOINs (also nur mit WHERE Bedingung) im Hintergrund einen FULL JOIN draus.
        Wenn du aber schon vorher definierst, was du brauchst (INNER / RIGHT / LEFT / .. JOIN) kannst du die Abfrage somit optimieren.

        Du koenntest auch noch mit Indizes arbeiten (zB: nonclustered index (MS SQL)) aber wenn es dir einen solchen Index zerstoert, kann das echt horrible Folgen haben; wuerde die Sache aber zusaetzlich beschleunigen.
        *-- robert.oh. --*

        Comment


        • #5
          Hallo Robert,

          ich habe jetzt die Abfrage auf joins umgesetzt. Test läuft immer noch. Deutlich langsamer.
          Ich werde mal einen anderen Ansatz nehmen. Das Feld Kundenname ist nur für den Anwender interessant. Ich werde dieses Feld bei der Anzeige nachschlagen. Vermutlich wird es dann etwas schneller.
          Richtig zufrieden bin ich damit aber nicht. Ich glaube eigentlich, dass da was direkt in der Abfrage verbessert werden muss.

          Vielen Dank erst einmal

          Gruß

          Peter

          Comment


          • #6
            Schade
            Ich dachte das wuerde helfen.
            *-- robert.oh. --*

            Comment


            • #7
              Hallo Peter,

              - Wie sieht der PLAN aus?
              - Welche Indizes existieren auf diesen Tabellen?
              - Ist das Feld ID in der Tabelle Kunde der Primärschlüssel, dann ist das OR (k.id is null) überflüssig
              - Parameter mit LIKE fördern nicht wirklich die Performance, weil hier nie ein Index verwendet wird, weil IB/FB beim Prepare ja nicht wissen kann, welchen Wert (z.B. 'WERT' oder 'WERT%' oder '%WERT%' oder was auch immer) dieser Parameter einnehmen wird

              Nur so ein paar schnelle Gedanken. ;-)


              Thomas
              Thomas Steinmaurer

              Firebird Foundation Committee Member
              Upscene Productions - Database Tools for Developers
              Mein Blog

              Comment


              • #8
                Hallo Thomas,

                ich habe mittlerweile die Abfrage verändert.
                Statt eine Summe zu bilden (und die damit erzwungenen Gruppierungen) rufe ich jetzt nur noch den Preis ab.

                Vorteil: Dauer ca. 2 Sek.
                Nachteil: Keine Summe über den Tagesumsatz

                Ist zur Zeit zu verschmerzen. Die Indizierungen laufen zur Zeit nur über die ID. Id ist bei mir immer eindeutig und wird mit einem Generator verknüpft.

                Also in der Tabelle Verkaufsdetails sind auch die Informationen zum Verkäufer (KID) und zum Verkaufsvorgang (VKID).

                Verkäufer kann NULL sein, da dieser gelöscht werden darf, falls nicht mehr aktiv und vom Kunden gewünscht (Datenschutz).

                Das "like" wurde eingeführt, um zwischen einer leeren Anweisung oder einer spezifizierten zu unterscheiden. Also Kundennummer bekannt oder egal. Du hast aber recht. Hier habe ich nicht weiter gedacht.
                Hiesse also, die SelectSQL zur Laufzeit abändern in "is NULL" oder "= "irgendwas".

                Danke dir!

                Gruß

                Peter
                Zuletzt editiert von petermaennchen; 24.03.2007, 22:27.

                Comment

                Working...
                X