Frage

Ich habe eine gespeicherte Prozedur, die eine Ansicht verwendet 6 mittelt zu ziehen. Die SQL-Datenbank ist SQL Server 2000. Wenn ich es im Query Analyzer ausführen, dauert es ungefähr 9 Sekunden. Was kann ich eine bessere Leistung tun? Soll ich die Zeilen mit LINQ zurückgeben und eine durchschnittliche bestimmen auf diese Weise? Wird es schneller sein?

Hier ist ein Beispiel meiner aktuellen sproc:

create procedure [TestAvg]
(
    @CustomerNumber int
)
as

select
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 7 and CustomerNumber = @CustomerNumber) as P12D7,
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 30 and CustomerNumber = @CustomerNumber) as P12D30,
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 90 and CustomerNumber = @CustomerNumber) as P12D90,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 7 and CustomerNumber = @CustomerNumber) as P16D7,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 30 and CustomerNumber = @CustomerNumber) as P16D30,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 90 and CustomerNumber = @CustomerNumber) as P16D90

Auch, lassen Sie mich die Ansicht oben genannten klären. Da diese SQL Server 2000 ist, kann ich nicht eine indizierte Sicht verwenden, da es eine Unterabfrage nicht verwendet. Ich nehme an, dies neu geschrieben werden kann, um den Einsatz verbindet. Allerdings haben wir das letzte Mal eine Abfrage nahm und schrieb es auf den Einsatz verbindet, fehlt Daten (da die Unterabfrage einen Nullwert zurückgeben kann, die die gesamte Zeile weglassen würde).

War es hilfreich?

Lösung

Ich würde empfehlen, die Daten in eine Tabelle var immer zuerst, vielleicht 2 Tabelle Vars, 1 12 und 1 16 ProductID. Aus diesem Tisch Vars, berechnet die AVGs je nach Bedarf, und dann wieder toste vom sp.

DECLARE @OrderDetails12 TABLE(
        DateFulfilled DATETIME,
        OrderTime FLOAT
)

INSERT INTO @OrderDetails12
SELECT  DateFulfilled,
        OrderTime
FROM    OrderDetails
WHERE   ProductID = 12
AND     DateDiff(day, DateFulfilled, GetDate()) <= 90
and CustomerNumber = @CustomerNumber

DECLARE @OrderDetails16 TABLE(
        DateFulfilled DATETIME,
        OrderTime FLOAT
)

INSERT INTO @OrderDetails16
SELECT  DateFulfilled,
        OrderTime
FROM    OrderDetails
WHERE   ProductID = 16
AND     DateDiff(day, DateFulfilled, GetDate()) <= 90
and CustomerNumber = @CustomerNumber

Auch die richtigen Indizes für die Tabelle erstellen, wird eine große Hilfe sein.

Andere Tipps

Was wäre die Menge an Daten, der Datenbankserver verlassen, wenn es nicht aggregierte war und wie lange diese Operation zu tun? Der Unterschied in der Größe der Daten führt, ob die Rechenzeit auf dem Server durch die Transferzeit und lokale Berechnung aufgewogen wird.

Auch - Blick auf diese DATEDIFF Nutzung und ändern Sie es leichter zu sein, es optimierbar zu machen (Versuch DateFullfilled> = SomeCalculatedDate1 statt DATEDIFF) - Ihre Ausführungsplan überprüfen, um sicherzustellen, dass es in der Lage ist, einen Index zu verwenden suchen (am besten) oder Index-Scan (gut) anstelle eines table_scan.

Sie außerdem sicher, gibt es einen Index auf Kundennummer, ProduceID, DateFulfilled.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top