Mit T-SQL AVG oder Mittelwert nimmt nach Ergebnissen mithilfe von LINQ zurückgegeben
-
20-09-2019 - |
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).
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.