استخدام T-SQL AVG أو أخذ المتوسط ​​بعد إرجاع النتائج باستخدام LINQ

StackOverflow https://stackoverflow.com/questions/1757446

سؤال

لدي إجراء مخزن يستخدم طريقة عرض لسحب 6 متوسطات.قاعدة بيانات SQL هي SQL Server 2000.عندما أقوم بتشغيله في محلل الاستعلام، يستغرق الأمر حوالي 9 ثوانٍ.ما الذي يمكنني فعله للحصول على أداء أفضل؟هل يجب علي إرجاع الصفوف باستخدام LINQ وتحديد المتوسط ​​بهذه الطريقة؟هل سيكون أسرع؟

فيما يلي مثال على 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

واسمحوا لي أيضًا أن أوضح وجهة النظر المذكورة أعلاه.نظرًا لأن هذا هو SQL Server 2000، فلا يمكنني استخدام طريقة عرض مفهرسة لأنها تستخدم استعلامًا فرعيًا.أفترض أنه يمكن إعادة كتابة هذا لاستخدام الصلات.ومع ذلك، في المرة الأخيرة التي أخذنا فيها استعلامًا وأعدنا كتابته لاستخدام الصلات، كانت البيانات مفقودة (لأن الاستعلام الفرعي يمكن أن يُرجع قيمة فارغة تؤدي إلى حذف الصف بأكمله).

هل كانت مفيدة؟

المحلول

أود أن أوصي بإدخال البيانات في جدول var أولاً، وربما جدولين vars، و1 لـ 12 و1 لـ 16 ProductID.من هذه الجداول، احسب المتوسطات كما هو مطلوب، ثم ارجع إلى tose من 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

كما أن إنشاء الفهارس الصحيحة على الجدول سيساعد كثيرًا.

نصائح أخرى

ما هي كمية البيانات التي تغادر خادم قاعدة البيانات إذا كانت غير مجمعة، وما هي المدة اللازمة للقيام بهذه العملية؟سيوجه الاختلاف في حجم البيانات ما إذا كان وقت الحساب على الخادم يفوق وقت النقل والحساب المحلي.

أيضا - انظر إلى ذلك DATEDIFF الاستخدام وتغييره ليكون أسهل لجعله قابلاً للتحسين (جرب DateFullfilled >= SomeCalculatedDate1 بدلاً من DATEDIFF) - راجع خطة التنفيذ الخاصة بك للتأكد من أنها قادرة على استخدام بحث الفهرس (الأفضل) أو فحص الفهرس (جيد) بدلاً من table_scan.

تأكد أيضًا من وجود فهرس على CustomerNumber، ProduceID، DateFulfilled.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top