AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi SQL Abfrage über mehrere Tabellen beschleunigen
Thema durchsuchen
Ansicht
Themen-Optionen

SQL Abfrage über mehrere Tabellen beschleunigen

Ein Thema von hirnstroem · begonnen am 15. Nov 2007 · letzter Beitrag vom 20. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
hirnstroem

Registriert seit: 21. Sep 2005
297 Beiträge
 
Delphi 2006 Professional
 
#1

SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 15. Nov 2007, 12:14
Datenbank: Access • Version: kA • Zugriff über: ADO
'loha Folks,

untenstehende Abfrage führt ab einer gewissen Anzahl Datensätzen in den verschiedenen Tabellen zu relativ grossen Geschwindigkeitseinbussen:

SQL-Code:
SELECT *
FROM
(Device_Key RIGHT JOIN
  (Room INNER JOIN
    (Floor INNER JOIN
      (DeviceType INNER JOIN
        (Building INNER JOIN
          (Application INNER JOIN
            Device
          ON [Application].[ApplicationID] =[Device].[ApplicationID])
        ON [Building].[BuildingID] =[Device].[BuildingID])
      ON [DeviceType].[DeviceTypeID] =[Device].[DeviceTypeID])
    ON [Floor].[FloorID] =[Device].[FloorID])
  ON [Room].[RoomID] =[Device].[RoomID])
ON [Device_Key].[DeviceID] = [Device].[DeviceID])
WHERE
DeviceType = :DeviceType
AND
[Device_Key].[KeyID] = :KeyID
ORDER BY Address;
Dass die Abfrage mit ansteigender Anzahl der davon betroffenen Datensätzen immer langsamer wird leuchtet mir ein. Die Situation ist aber die folgende:

- Die Tabelle "Device" enthält bis zu max. 512 Geräte
- Die Tabelle "Key" enthält bis zu max. 2000 Schlüssel
- Die Tabelle "Device_Key" enthält folglich bis zu 1'024'000 Einträge (welche dann auch das Problem zu sein scheinen)

Obige Abfrage soll sämtliche Geräte (sowie zusätzliche Infos wie die Angabe in welchem Raum sich das Gerät befindet, etc.) auflisten, welchen ein Schlüssel zugeordnet ist. Dies dauert im Extremfall (512 Geräte mit jeweils 2000 Schlüsseln) weit über zehn Sekunden auf meinem Computer.

Nun fehlt es mir etwas an Erfahrung bezüglich dem Umgang mit Datenbanken und ich wollte mich erkundigen, mit welcher Geschwindigkeit ihr unter den genannten Voraussetzungen in etwa rechnen würdet, beziehungsweise, wo man ansetzen könnte, um die Geschwindigkeit der Abfrage etwas zu beschleunigen.

Meine bisherigen Versuche, die Indizierung verschiedener Felder zu aktivieren / deaktivieren, hat bisher nichts gebracht.

Grüsse
hrinstroem
inde deus abest
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 15. Nov 2007, 12:26
Zitat von hirnstroem:
Meine bisherigen Versuche, die Indizierung verschiedener Felder zu aktivieren / deaktivieren, hat bisher nichts gebracht.
Schau dir mal die ON - Verknüpfungen an:
SQL-Code:
          ON [Application].[ApplicationID] =[Device].[ApplicationID])
        ON [Building].[BuildingID] =[Device].[BuildingID])
      ON [DeviceType].[DeviceTypeID] =[Device].[DeviceTypeID])
    ON [Floor].[FloorID] =[Device].[FloorID])
  ON [Room].[RoomID] =[Device].[RoomID])
ON [Device].[DeviceID] = [Device_Key].[DeviceID])
Die Felder auf der linken Seite (also [Application].[ApplicationID], usw.) sind ja alles Primärschlüsselkandidaten.
Ich hoffe du hast auf allen 6 Tabellen einen Primärschlüssel gesetzt.
Die Felder auf der rechten Seite ([Device].[ApplicationID], ...) sind alles Fremdschlüssel.
Alle diese Felder sollten einen Index haben.
Dabei hast du die Wahl zwischen je einem Index pro Fremdschlüsselfeld und der Kombination mehrerer Fremdschlüsselfelder zu einem Index.
Wenn ein Index mehrere Felder umfasst, hat das gewisse Performancevorteile; aber nur dann wenn alle beteiligten Felder auch in der Abfrage benützt werden. (es gibt noch Ausnahmen von dieser Regel, aber das führt im Moment zu weit)
Andreas
  Mit Zitat antworten Zitat
hirnstroem

Registriert seit: 21. Sep 2005
297 Beiträge
 
Delphi 2006 Professional
 
#3

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 15. Nov 2007, 13:55
Zitat von shmia:
Ich hoffe du hast auf allen 6 Tabellen einen Primärschlüssel gesetzt.
Ja, dem ist so. Mittlerweile habe ich auch herausgefunden, dass wenn die Fremdschlüssel keinen Index haben, die Abfrage noch viel langsamer Ausgeführt wird.

Aber ob nun zehn Sekunden, für das herausfiltern von 512 Datensätzen aus einer Menge von 1'024'000 Datensätzen, eine gute Zeit sind oder nicht, kann ich noch immer nicht so richtig beurteilen.

Vielen Dank für deine Ausführungen Andreas.

Grüsse
hirnstroem
inde deus abest
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 15. Nov 2007, 14:16
Es gibt noch weitere Optimierungsmöglichkeiten.
Deine Abfrage mit SELECT * FROM ... ist schlecht, da so alle Felder aus allen Tabellen gezogen werden.
Viele Felder sind dann doppelt vorhanden.
Besser so:
SELECT Device.*, Building.Adress, ... FROM Das *-chen darf man nur einmal auf eine Tabelle anwenden.
Alle anderen Felder sollten voll qualifiziert angegeben werden.
Je weniger Daten du abrufst umso schneller die Abfrage.
Und bei Access ist CursorLocation = clUseServer schneller als clUseClient.
Andreas
  Mit Zitat antworten Zitat
hirnstroem

Registriert seit: 21. Sep 2005
297 Beiträge
 
Delphi 2006 Professional
 
#5

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 15. Nov 2007, 14:30
Nun gut, in diesem Falle werden, bis auf die jeweiligen Hauptschlüssel, sämtliche Daten auf einem Webinterface dargestellt. Die CursorLocation ist aber in der Tat beim Client. Da maximal 512 Geräte respektive 2000 Schlüssel in der Datenbank vorkommen, sollte dies aber nicht übermässig ins Gewicht fallen. Zudem meine ich, dass ein serverseitiger Cursor noch andere Probleme nach sich zieht (aufgrund spezieller Filter oder Sortierungen, habe es einmal ausprobiert und bin schnell angestanden).

Werde das ganze noch auf einer nicht Access Datenbank durchspielen, wenn sich mir die Gelegenheit bietet, das könnte vielleicht noch aufschlussreich sein.
inde deus abest
  Mit Zitat antworten Zitat
hirnstroem

Registriert seit: 21. Sep 2005
297 Beiträge
 
Delphi 2006 Professional
 
#6

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 20. Nov 2007, 13:50
SQL-Code:
SELECT *
from device_key, device, deviceType, Building, Floor, Room, Application
where device_key.keyID = :KeyID
and deviceType.deviceType = "Door Interface"
and device_key.deviceId = device.deviceId
and device.deviceTypeId = deviceType.deviceTypeId
and device.buildingID = Building.buildingID
and device.floorId = Floor.floorId
and device.RoomId =Room.RoomId
and device.ApplicationId = Application.ApplicationId
^^ liefert dieselben Ergebnisse wie jene Abfrage mit den komisch verschachtelten Joins, nur um ein vielfaches schneller. Nun dauert das ganze ein Paar Millisekunden, was, im Vergleich zu der halben Minunte bei der Abfrage zuvor, recht gut ist.

Grüsse
hirnstroem
inde deus abest
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 20. Nov 2007, 13:59
Zitat von hirnstroem:
dass ein serverseitiger Cursor noch andere Probleme nach sich zieht .
Normalerweise sollte man bei Access immer Serverseitigen Curser verwenden, um ein 1* Speicherkopieren zu vermeiden (Access ist ja kein Server und nötige DLL's sind ja im Client-Adressraum geladen.

Zitat von hirnstroem:
^^ liefert dieselben Ergebnisse wie jene Abfrage mit den komisch verschachtelten Joins, nur um ein vielfaches schneller. Nun dauert das ganze ein Paar Millisekunden, was, im Vergleich zu der halben Minunte bei der Abfrage zuvor, recht gut ist
Da vermute ich mal das die vielen Joins einfach zu viel des guten für die Jet-Engine waren und er einfach intern auf stupide Full Table-Scan geschaltet hat.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#8

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 20. Nov 2007, 14:00
Du hattest ja in deiner ersten Abfrage (die mit den Joins) ja auch ein RIGHT OUTER JOIN stehen.... OUTER JOINS sind wesentlich langsamer als FULL JOINS.
  Mit Zitat antworten Zitat
hirnstroem

Registriert seit: 21. Sep 2005
297 Beiträge
 
Delphi 2006 Professional
 
#9

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 20. Nov 2007, 14:17
Zitat von Bernhard Geyer:
Da vermute ich mal das die vielen Joins einfach zu viel des guten für die Jet-Engine waren und er einfach intern auf stupide Full Table-Scan geschaltet hat.
Wird wohl so etwas in dieser Art gewesen sein.


Zitat von Jelly:
Du hattest ja in deiner ersten Abfrage (die mit den Joins) ja auch ein RIGHT OUTER JOIN stehen.... OUTER JOINS sind wesentlich langsamer als FULL JOINS.
Und ich bin davon ausgegangen, dass, wenn es schon so schöne Join-Konstrukte gibt, diese auch schneller sind als andere, herkömliche Schreibweisen.
inde deus abest
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#10

Re: SQL Abfrage über mehrere Tabellen beschleunigen

  Alt 20. Nov 2007, 14:21
Zum Verständnis:
Bei einem INNER JOIN werden aus den beiden betroffenen Tabellen nur die Datensätze berücksichtigt, die übereinstimmen. Bei einem outer join werden bei einer Tabelle ALLE Datensätze herbeigezogen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz