2009-05-06 20 views
0

Im Moment habe ich diese SQL-Abfrage, die gültig ist, aber immer mal aus:Wie kann ich diese SQL-Abfrage optimieren?

SELECT 
(
SELECT (MAX(WP_ODOMETER) - MIN(WP_ODOMETER))/DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME)) 
FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
AND WP_VTDID = 'L088' 
) 
AS MAXD, 
(
SELECT MAX(WP_ODOMETER) 
FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
AND WP_VTDID = 'L088' 
) 
AS MD 

Ich möchte eine Ansicht erstellen auf der oben genannten SQL-Abfrage basiert. Etwas wie dieses:

SELECT L_VTDID 
(
SELECT (MAX(WP_ODOMETER) - MIN(WP_ODOMETER))/DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME)) 
FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
AND WP_VTDID = LOCOMOTIVES.L_VTDID 
) 
AS MAXD, 
(
SELECT MAX(WP_ODOMETER) 
FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
AND WP_VTDID = LOCOMOTIVES.L_VTDID 
) 
AS MD 
FROM LOCOMOTIVES 
+1

Wenn Sie diese Art von Fragen stellen, ist es normalerweise eine gute Idee, einen Ausführungsplan zu veröffentlichen. –

+0

Ich wusste nicht, wie das geht: D, ich überprüfe Abfrage -> Geschätzten Ausführungsplan anzeigen, es sagte mein gruppierten Index suchen (etwa 34% auf jedem Feld bei Abfrage) – Dels

Antwort

1

Da sie die gleiche haben, wo Klausel, könnte man sie kombinieren:

SELECT 
MAX(WP_ODOMETER), 
(MAX(WP_ODOMETER) - MIN(WP_ODOMETER))/
DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME)) 
FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
AND WP_VTDID = 'L088' 

Ein Index für WP_VTDID, WP_DATETIME dies oben beschleunigen kann. Sie können auch WP_ODOMETER in den Index aufnehmen, um die Lesezeichen-Suche aus dem Index in die Tabelle selbst zu speichern.

Wenn das Timeout auftritt, weil jemand anderes auf den Tisch blockiert, versuchen die zu von Aussage zu ändern:

FROM WAYPOINTS (NOLOCK) 

Wenn die Abfrage mit NOLOCK fein läuft, ist ein anderer Prozess unter Verwendung der Tabelle und verhindert, dass Ihre Abfrage aus Sperren von Zeilen.

+0

Ich benutze Ihre Abfrage auch zuerst, aber es scheint langsamer, so verwende ich innere Auswahl, um zu beschleunigen (vielleicht ich falsch), und ja, ich habe bereits die wichtigen Felder indiziert – Dels

+0

Haben Sie den Abfrageausführungsplan überprüft? Menüabfrage, dann tatsächlicher oder geschätzter Ausführungsplan. Wenn dort ein Tabellenscan angezeigt wird, wird der Zinkenindex wahrscheinlich nicht verwendet. – Andomar

+0

Warum diese Obsession mit NOLOCK ???? –

0

Wird WAYPOINTS auf WP_DATETIME und WP_VTDID indiziert?

+0

ja, alle wichtigen Felder auf dieser Tabelle bereits indexiert – Dels

+1

Besser anzugeben, welche Felder indiziert sind - Sie könnten nicht wissen, welche wichtig sind. Gibt es auch zusammengesetzte Indizes (in mehreren Spalten) oder sind sie alle einzelne Spaltenindizes? Was ist die Größe der Tabelle (Anzahl der Zeilen, Breite der Zeile in Bytes, Anzahl der Spalten). –

3

es glauben oder nicht, Client-Seite Sprachen sind eigentlich durchaus in der Lage Subtraktion und Division tun, usw. Also, es waren zu mir, ich würde die Abfrage vereinfachen (vor allem, da diese Version Probleme gibt):

SELECT MAX(WP_ODOMETER) AS MAX_ODO, 
     MIN(WP_ODOMETER) AS MIN_ODO, 
     MIN(WP_DATETIME) AS MIN_DATE, 
     MAX(WP_DATETIME) AS MAX_DARE 
    FROM WAYPOINTS 
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE() 
    AND WP_VTDID = 'L088' 

Wenn es ein großes Problem bei der Verarbeitung von Datumsberechnungen auf der Client-Seite gibt, würde ich einräumen, dass Sie möglicherweise den Unterschied zwischen MAX_DATE und MIN_DATE auf dem Server generieren müssen, aber es könnte besser sein, eine Hostsprache zu bekommen ermöglicht Ihnen, Datumsberechnungen durchzuführen.

+0

Wie würde die Verschiebung einer einzelnen Abteilung vom Server zum Client eine langsame Abfrage beschleunigen? – Andomar

+0

Es bewegt die Teilung nicht; Es ersetzt zwei Unterabfragen in der SELECT-Liste durch eine einfachere Menge von Ausdrücken, die helfen. Die ursprüngliche Abfrage berechnet sowohl 'MAX_ODO' als auch den Ausdruck über die Zeit (ungefähr die durchschnittliche zurückgelegte Strecke pro Tag) als zwei getrennte Unterabfragen. Ich habe sie durch eine einzige (nicht untergeordnete) Abfrage ersetzt. –