![]() |
Datenbank: MySQL • Version: 4.x • Zugriff über: Zeos
SQL-Abfrage dauert zu lange
Hallo Leute,
bei folgende SQL-Abfrage dreht mein Rechner durch. PHPMyAdmin benötigt für das Ergebnis 7 Sekunden, Delphi mit Zeos kommt sogar auf Minuten. Hab ich nun einen Denkfehler in die Abfrage eingebaut oder ist das normal? Folgende Sachen sind gegeben: Tabellen: kasse_vorgaenge, kasse_rechnungen, kasse_gutschriften, kasse_lieferscheine In jedem einzelnen Datensatz von "kasse_vorgaenge" steht in der Spalte "vorgangsart", ob es sich um eine Rechnung, Lieferschein oder Gutschrift handelt. Mit
Delphi-Quellcode:
komme ich ganz normal weiter. Nun möchte ich jedoch auch die jeweilige Rechnungs-, Gutschrifts- bzw. Lieferscheinnummer dabei haben, die in den anderen drei Tabellen stehen.
SELECT * FROM kasse_vorgaenge WHERE kundennummer = 1 WHERE datum BETWEEN 2006-05-01 AND 2006-11-28
Also nehme ich folgende Abfrage:
Delphi-Quellcode:
Hat jemand eine Idee, wie ich das Ergebnis schneller bekomme?
SELECT
kasse_vorgaenge.*, kasse_rechnungen.ID, kasse_gutschriften.ID, kasse_lieferscheine.ID FROM kasse_vorgaenge, kasse_rechnungen, kasse_gutschriften, kasse_lieferscheine WHERE kasse_vorgaenge.kundennummer = 1 AND kasse_vorgaenge.datum BETWEEN 2006-05-01 AND 2006-11-28 AND kasse_rechnungen.vorgangsnummer = kasse_vorgaenge.ID OR kasse_gutschriften.vorgangsnummer = kasse_vorgaenge.ID OR kasse_lieferscheine.vorgangsnummer = kasse_vorgaenge.ID GROUP BY kasse_vorgaenge.ID MfG davar |
Re: SQL-Abfrage dauert zu lange
Das ist ein ziemlich komplexes Thema (optimierung von Queries)
Was du zuerst prüfen solltest: Sind die Indizes (von manchen auch Indexe genannt) korrekt gesetzt. In deinem Fall bei Tabelle kasse_vorgaenge z.B. auf kundennummer und datum und in den anderen Tabellen die jeweiligen Vorgangsnummern. Wenn immer möglich benutze InnerJoin In deinem Fall würde ich Sub-Selects verwenden |
Re: SQL-Abfrage dauert zu lange
Es scheinen auch Klammern zu fehlen.
|
Re: SQL-Abfrage dauert zu lange
Hallo,
Outer Join ? Das hier sind doch auch inner joins, nur halt die alte Syntax. Ich würde hier entweder 3 Queries machen, und dass dann am Client zusammenbauen, oder eine Stored Procedure, die intern ebenfalls auf 3 Queries aufbaut, (+ der Query für den kasse_vorgangs_id Cursor). Heiko |
Re: SQL-Abfrage dauert zu lange
Durch die BETWEEN - Abfrage wird die Datenbank auf jeden Fall einen Full Table Scan machen. Und das leider zwangsläufig auf allen Tabellen. Und ein FTS ist so ziemlich das Schlimmste was Dir bei der Performance passieren kann.
Versuch mal, die Between-Abfrage rauszulassen und schau, wie das Laufzeitverhaltend es Queries dann ist. Setze zudem noch Indizes auf die abgefragten Spalten. Die Auswahl nach dem Datum machst Du dann im Client. Das dürfte performanter sein. Ausnahme: Du setzt vorher einen Index auf das Datum und machst eine materialized View die Dir die Tabelle nach dem Datum eingrenzt. Das Problem wird hier aber sein, dass das Datum ja eher dynamischer Natur ist und damit fällt die View an der Stelle wohl weg. |
Re: SQL-Abfrage dauert zu lange
Zitat:
Ein "x BETWEEN a AND b"ist -zumindest bei MSSQL- genau das Gleiche wie "x>=a AND x<=b". Wieso sollte er einen FTS machen? Sofern X indiziert ist, kann der Server doch toll optimieren. |
Re: SQL-Abfrage dauert zu lange
Kannst Du mal sagen, wie viele Datensätze in den einzelnen Tabellen sind?
Ich tippe auch eher auf die Richtung, die mkinzler ansprach. Deine Abfrage sucht Dir nebenbei mal alle Datensätze aus "kasse_gutschriften" und "kasse_lieferscheine" deren Vorgangsnummer = kasse_vorgaenge.ID ist. Dazu kommen dann noch die Datensätze aus kasse_rechnungen die zu den aus kasse_vorgaenge selektierten passen. Wenn Du die OR-Bedingungen in Klammern setztest, würdest Du eher das Ergebnis bekommen, das Du haben möchtest und wahrscheinlich geht die Abfrage dann auch schneller. |
Re: SQL-Abfrage dauert zu lange
Hallo davar,
vielleicht so...
SQL-Code:
Gruss
SELECT kv.*,
kr.ID, kg.ID, kl.ID FROM kasse_vorgaenge kv LEFT JOIN kasse_rechnungen kr ON kv.ID = kr.vorgangsnummer LEFT JOIN kasse_gutschriften kg ON kv.ID = kg.vorgangsnummer LEFT JOIN kasse_lieferscheine kl ON kv.ID = kl.vorgangsnummer WHERE kv.kundennummer = 1 AND kv.datum BETWEEN '2006-05-01' AND '2006-11-28' Thorsten |
Re: SQL-Abfrage dauert zu lange
Wie erkennt man denn, dass die Datenbank einen Full Table Scan macht?
Sieht man das im Profiler? Wenn ja woran? |
Re: SQL-Abfrage dauert zu lange
Du musst doch nur einen Index über die Datumsspalte machen, dann macht kein normales DBMS einen 'full table scan'. Oder Ist MySQL etwa kein normales DBMS?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz