سؤال

أحاول تحسين بعض استعلامات SQL المعقدة بشكل مروع لأن الأمر يستغرق وقتًا طويلاً للغاية.

في استفساراتي ، قمت بإنشاء عبارات SQL ديناميكيًا مع الكثير من الوظائف نفسها ، لذلك قمت بإنشاء جدول مؤقت حيث تسمى كل وظيفة مرة واحدة فقط بدلاً من عدة مرات - هذه تقليص وقت التنفيذ بمقدار 3/4.

لذا فإن سؤالي هو ، هل يمكنني أن أتوقع أن أرى الكثير من الفرق إذا قيل ، يتم تضييق 1000 حساب Datediff إلى 100؟

تحرير: الاستعلام يشبه هذا:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

عندما يتم توليدها ديناميكيًا كسلاسل (تجمع في أجزاء وقطع) ثم يتم تنفيذها بحيث يمكن تغيير المعلمات المختلفة على طول كل تكرار - خاصة الأسطر الأخيرة ، التي تحتوي على جميع أنواع استعلامات المؤرخ.

هناك حوالي 420 استعلام مثل هذا حيث يتم حساب هؤلاء المواعدين مثل ذلك. أعلم أنه يمكنني سحبهم جميعًا إلى طاولة مؤقتة بسهولة (يصبح 1000 مؤرخ 50) - ولكن هل يستحق ذلك ، هل سيحدث أي فرق في الثواني؟ آمل أن يكون ذلك أفضل من أعشار الثواني.

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

المحلول

يعتمد ذلك على ما تفعله بالضبط لتكون صادقًا فيما يتعلق بمدى نجاح الأداء.

على سبيل المثال ، إذا كنت تستخدم Datediff (أو في الواقع أي وظيفة أخرى) ضمن شرط حيث ، فسيكون هذا سببًا للأداء الأكثر فقراً لأنه سيمنع فهرس يستخدم في هذا العمود.

على سبيل المثال ، مثال أساسي ، العثور على جميع السجلات في عام 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

لن يستفيد بشكل جيد من فهرس على بيانات البيانات. في حين أن الحل الأفضل ، فإن توفير استخدام الفهرس الأمثل سيكون:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

أنا تم التدوين مؤخرًا حول الفرق الذي يحدثه هذا (مع إحصائيات الأداء/مقارنات خطة التنفيذ) ، إذا كنت مهتمًا.

سيكون ذلك أكثر تكلفة من القول بالعودة المؤرخة كعمود في ResultSet.

أود أن أبدأ بتحديد الاستعلامات الفردية التي تستغرق معظم الوقت. تحقق من خطط التنفيذ لمعرفة أين تكمن المشكلة والضبط من هناك.

يحرر:استنادًا إلى استفسار المثال الذي قدمته ، إليك نهجًا يمكنك تجربة استخدام استخدام Datediff داخل الفقرة. مثال أساسي للعثور على كل من كان عمره 10 سنوات في تاريخ معين - أنا فكر في الرياضيات صحيحة ، لكنك تحصل على الفكرة على أي حال! أعطاها اختبارًا سريعًا ، ويبدو جيدًا. يجب أن يكون سهلاً بما يكفي للتكيف مع السيناريو الخاص بك. إذا كنت ترغب في العثور على أشخاص بين (على سبيل المثال) 15 و 17 عامًا في تاريخ معين ، فهذا ممكن أيضًا مع هذا النهج.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

ملاحظة مهمة لإضافتها ، هي لقرن عصر من DOB ، هذا النهج أكثر دقة. لا يستغرق تطبيقك الحالي سوى عام الولادة في الاعتبار ، وليس اليوم الفعلي (على سبيل المثال ، سيظهر شخص مولود في الأول من ديسمبر 2009 على أنه عمره عام واحد في الأول من يناير 2010 عندما لا يكون 1 حتى 1 ديسمبر 2010).

أتمنى أن يساعدك هذا.

نصائح أخرى

Datediff فعال للغاية مقارنة بالطرق الأخرى للتعامل مع قيم DateTime ، مثل السلاسل. ((انظر هذا حتى الإجابة).

في هذه الحالة ، يبدو أنك تتجاوز البيانات نفسها ، والتي من المحتمل أن تكون أغلى من استخدام جدول مؤقت. على سبيل المثال ، سيتم إنشاء الإحصائيات.

شيء واحد قد تكون قادرًا على القيام به لتحسين الأداء هو وضع فهرس على جدول مؤقت في منتصف.

تحقق من خطة التنفيذ الخاصة بك لمعرفة ما إذا كانت تساعد (قد تعتمد على عدد الصفوف في جدول مؤقت).

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