![]() |
Datenbank: Access • Version: kA • Zugriff über: ADO
SQL Abfrage über mehrere Tabellen beschleunigen
'loha Folks,
untenstehende Abfrage führt ab einer gewissen Anzahl Datensätzen in den verschiedenen Tabellen zu relativ grossen Geschwindigkeitseinbussen:
SQL-Code:
Dass die Abfrage mit ansteigender Anzahl der davon betroffenen Datensätzen immer langsamer wird leuchtet mir ein. Die Situation ist aber die folgende:
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; - 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 |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
Zitat:
SQL-Code:
Die Felder auf der linken Seite (also [Application].[ApplicationID], usw.) sind ja alles Primärschlüsselkandidaten.
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]) 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) |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
Zitat:
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 |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
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:
Delphi-Quellcode:
Das *-chen darf man nur einmal auf eine Tabelle anwenden.
SELECT Device.*, Building.Adress, ... FROM
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. |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
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. |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
SQL-Code:
^^ 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.
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 Grüsse hirnstroem |
Re: SQL Abfrage über mehrere Tabellen beschleunigen
Zitat:
Zitat:
|
Re: SQL Abfrage über mehrere Tabellen beschleunigen
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.
|
Re: SQL Abfrage über mehrere Tabellen beschleunigen
Zitat:
Zitat:
|
Re: SQL Abfrage über mehrere Tabellen beschleunigen
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:24 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 by Thomas Breitkreuz