مختلفة خطة التنفيذ عند تنفيذ البيان مباشرة من الإجراء المخزن

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

سؤال

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

هنا الاستعلام

SELECT     
    DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)) AS Day, 
    DATEPART(hh, TableA.Created) AS [Hour], 
    SUM(TableB.Quantity) AS Quantity, 
    SUM(TableB.Amount) AS Amount
FROM
    TableA
    INNER JOIN TableB ON TableA.BID = TableB.ID
WHERE     
    (TableA.ShopId = @ShopId)
GROUP BY 
    DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)), 
    DATEPART(hh, TableA.Created)
ORDER BY 
    DATEPART(hh, TableA.Created)

عند تشغيل استعلام "الخام" أحصل على تتبع التالي احصائيات

Event Class         Duration  CPU  Reads Writes
SQL:StmtCompleted   75        41      7      0

و عند تشغيل الاستعلام كما proc المخزنة باستخدام الأمر التالي

DECLARE @ShopId int
SELECT @ShopId = 1
EXEC spStats_GetSalesStatsByHour @ShopId

أحصل على تتبع التالي احصائيات

Event Class         Duration  CPU  Reads Writes
SQL:StmtCompleted   222       10     48      0

أنا أيضا الحصول على نفس النتيجة إذا كنت مخزن الاستعلام في nvarchar وتنفيذه باستخدام sp_executesql مثل هذا (ينفذ مثل sproc)

DECLARE @SQL nvarchar(2000)
SET @SQL = 'SELECT DATEADD(dd, ...'
exec sp_executesql @SQL

الإجراء المخزن لا يحتوي على أي شيء باستثناء select أعلاه.ما من شأنه أن يسبب ملقم sql إلى اختيار أقل شأنا خطة التنفيذ فقط لأن البيان هو تنفيذ الإجراء المخزن?

نحن حاليا يعمل على SQL Server 2000

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

المحلول

عموما هذا له علاقة مع المعلمة استنشاق.يمكن أن يكون محبطا للغاية للتعامل معها.في بعض الأحيان يمكن أن يكون حلها عن طريق ترجمة الإجراء المخزن, و في بعض الأحيان يمكنك حتى استخدام نسخة مكررة متغير داخل الإجراء المخزن مثل هذا:

alter procedure p_myproc (@p1 int) as
declare @p1_copy int;
set @p1_copy = @p1;

ومن ثم استخدام @p1_copy في الاستعلام.يبدو سخيفا لكنه يعمل.

تحقق من بلدي الأخيرة السؤال عن نفس الموضوع:

لماذا SqlServer محسن الحصول على الخلط حتى مع المعلمات ؟

نصائح أخرى

نعم -- كنت قد رأيت هذا على Oracle DB 11g وكذلك نفس الاستعلام ركض بسرعة على 2 العقد من db server في SQL موجه ولكن عندما دعا من حزمة حرفيا السماعة!

كان واضحا المشتركة مسبح للحصول على مطابقة السلوك:سبب بعض الوظائف/script كان قيد التشغيل التي قد أقدم نسخ تخوض في مكتبة ذاكرة التخزين المؤقت/الذاكرة على عقدة واحدة مع أدنى خطة التنفيذ.

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