= schnell, quaelend langsam

20/05/2009 - 16:38 von Christoph Schneegans | Report spam
Hallo allerseits!

Ich habe in einer Anwendung folgende Abfrage:

SELECT
a.AccountID,
Sum(Hours*Percentage/100) AS Stunden

FROM (((Accounts AS a
INNER JOIN Contingents AS cnt
ON a.AccountID = cnt.AccountID)
INNER JOIN Packages AS p
ON cnt.PackageID = p.PackageID)
INNER JOIN Bookings AS b
ON p.PackageID = b.PackageID)
INNER JOIN Employees AS e
ON b.EmployeeID = e.tblEmployeeID

WHERE
b.Date>=#4/1/2009#
AND b.Date<#5/1/2009#
AND p.PackageID(5

GROUP BY
a.AccountID;

Diese Abfrage wird ohne spürbare Verzögerung ausgeführt. Wenn ich
nun aber p.PackageID(5 durch p.PackageID<>285 ersetze, steigt die
Ausführungszeit dramatisch an. Das überrascht mich, denn 'PackageID'
ist natürlich der Primàrschlüssel in der Tabelle 'Packages', also
existiert ja auch ein entsprechender Index.

Gibt es eine Möglichkeit, die Abfrage zu beschleunigen? Sàmtliche
Tabellen sind übrigens in SQL Server angelegt und wurden in der
.mdb verknüpft.

<http://schneegans.de/web/xhtml/> · Klare Antworten zu XHTML
 

Lesen sie die antworten

#1 Josef Poetzl
20/05/2009 - 17:45 | Warnen spam
Hallo!

Christoph Schneegans schrieb:
[...]
WHERE
b.Date>=#4/1/2009#
AND b.Date<#5/1/2009#
AND p.PackageID(5

GROUP BY
a.AccountID;

Diese Abfrage wird ohne spürbare Verzögerung ausgeführt. Wenn ich
nun aber p.PackageID(5 durch p.PackageID<>285 ersetze, steigt die
Ausführungszeit dramatisch an.



WHERE
b.Date>=#4/1/2009#
AND b.Date<#5/1/2009#
AND p.PackageID(5

... wird zu Index-Seek über PackageID und Vergleich der Werte von
b.Date führen. Durch die Einschrànkung auf einen einzigen DS über
PackageID verringert sich die restliche Datenmenge.

bei
WHERE
b.Date>=#4/1/2009#
AND b.Date<#5/1/2009#
AND p.PackageID<>285

... bist du vermutlich gut bedient, wenn zuerst Date als Index
verwendet und erst dann der Ausdruck p.PackageID<>285 ausgewertet
wird.

Ein Index über Date ist aber schon verfügbar, oder?

bezüglich PackageID<>285 müsstest du einem Access/Jet-BE etwas helfen:
Jet schafft es nicht aus <> eine Indexverwendung zu machen und führt
einen Tablescan durch. (am besten im Jet-Showplan ansehen)

WHERE
b.Date>=#4/1/2009#
AND b.Date<#5/1/2009#
AND (p.PackageID<285 OR p.PackageID>285)


Das überrascht mich, denn 'PackageID'
ist natürlich der Primàrschlüssel in der Tabelle 'Packages', also
existiert ja auch ein entsprechender Index.



Der PK wird von PackageID wird nicht besonders viel helfen, wenn viele
DS in der Tabelle sind. Da kommt es vermutlich eher darauf an, dass
ein Index über b.Date genutzt werden kann, da das die Daten mehr
einschrànken wird. (Normalerweise sollte die passende
Abfrageausführung vom DBS gefunden werden.)

Gibt es eine Möglichkeit, die Abfrage zu beschleunigen? Sàmtliche
Tabellen sind übrigens in SQL Server angelegt und wurden in der
.mdb verknüpft.



Das finde ich allerdings eigenartig. Ich hàtte erwartet, dass der
gesamte SQL-Ausdruck (etwas abgewandelt) an den MSSQL-Server
durchgereicht wird.
Was kommt von Jet beim MSSQL-Server an? Hat du dir das im Profiler
schon einmal angesehen?

Oder:
Wie würde eigentlich die SQL-Anweisung im MSSQL (ohne Access-FE)
ausgeführt werden? Vielleicht ist bereits dort nach der Optimierung zu
suchen.


Noch etwas:
Vermutlich beschleunigst du das ganze noch viel mehr, wenn du die
SQL-Anweisung (ohne Filter-Ausdruck) als Sicht im Server ablegst, im
Access-FE diese Sicht verknüpfst und damit die Daten auswertest.
Dann kann MSSQL die Ausführung der Abfrage normalerweise besser
optimieren. Bei komplexeren joins in Access-Abfragen machte ich schon
öfter schlechte Erfahrung.


mfg
Josef

EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/

Ähnliche fragen