أوراكل تنفيذ التغييرات الفورية شرح خطة الاستعلام
-
04-10-2019 - |
سؤال
لدي إجراء مخزن أتصل به باستخدام تنفيذ فوري. المشكلة التي أواجهها هي أن خطة التوضيح مختلفة عندما أسمي الإجراء مباشرة مقابل عند استخدام تنفيذ فوري لاستدعاء الإجراء. هذا يسبب وقت التنفيذ لزيادة 5x. الفرق الرئيسي بين الخطط هو أنه عندما أستخدم تنفيذ فوري ، فإن المُحسِّن لا يفسد الاستماع الفرعي (أنا أستخدم شرطًا غير موجود). نحن نستخدم المحسن القائم على القواعد هنا في العمل في معظم الاستعلامات ، لكن هذا الاستعلامات لديه تلميح لاستخدام فهرس بحيث يتم استخدام CBO (ومع ذلك ، لا نجمع الإحصائيات على الجداول). نقوم بتشغيل إصدار Oracle9i Enterprise Edition 9.2.0.4.0 - 64 بت.
مثال: سريع:
begin
package.procedure;
end;
/
بطيء:
begin
execute immediate 'begin package.' || proc_name || '; end;';
end;
/
استفسار:
SELECT /*+ INDEX(A IDX_A_1) */
a.store_cd,
b.itm_cd itm_cd,
CEIL ( (new_date - a.dt) / 7) week_num,
SUM (a.qty * b.demand_weighting * b.CONVERT) qty
FROM a
INNER JOIN
b
ON (a.itm_cd = b.old_itm_cd)
INNER JOIN
(SELECT g.store_grp_cd, g.store_cd
FROM g, h
WHERE g.store_grp_cd = h.fdo_cd AND h.fdo_type = '1') d
ON (a.store_cd = d.store_cd AND b.store_grp_cd = d.store_grp_cd)
CROSS JOIN
dow
WHERE a.dt BETWEEN dow.new_date - 91 AND dow.new_date - 1
AND a.sls_wr_cd = 'W'
AND b.demand_type = 'S'
AND b.old_itm_cd IS NOT NULL
AND NOT EXISTS
(SELECT
NULL
FROM f
WHERE f.store_grp_cd = a.store_cd
AND b.old_itm_cd = f.old_itm_cd)
GROUP BY a.store_cd, b.itm_cd, CEIL ( (dow.new_date - a.dt) / 7)
خطة شرح جيدة:
OPERATION OPTIONS OBJECT_NAME OBJECT_TYPE ID PARENT_ID SELECT STATEMENT 0 SORT GROUP BY 1 0 NESTED LOOPS 2 1 HASH JOIN ANTI 3 2 TABLE ACCESS BY INDEX ROWID H 4 3 NESTED LOOPS 5 4 NESTED LOOPS 6 5 NESTED LOOPS 7 6 TABLE ACCESS FULL B 8 7 TABLE ACCESS BY INDEX ROWID A 9 7 INDEX RANGE SCAN IDX_A_1 UNIQUE 10 9 INDEX UNIQUE SCAN G UNIQUE 11 6 INDEX RANGE SCAN H_UK UNIQUE 12 5 TABLE ACCESS FULL F 13 3 TABLE ACCESS FULL DOW 14 2
خطة شرح سيئة:
OPERATION OPTIONS OBJECT_NAME OBJECT_TYPE ID PARENT_ID SELECT STATEMENT 0 SORT GROUP BY 1 0 NESTED LOOPS 2 1 NESTED LOOPS 3 2 NESTED LOOPS 4 3 NESTED LOOPS 5 4 TABLE ACCESS FULL B 6 5 TABLE ACCESS BY INDEX ROWID A 7 5 INDEX RANGE SCAN IDX_A_1 UNIQUE 8 7 TABLE ACCESS FULL F 9 8 INDEX UNIQUE SCAN G UNIQUE 10 4 TABLE ACCESS BY INDEX ROWID H 11 3 INDEX RANGE SCAN H_UK UNIQUE 12 11 TABLE ACCESS FULL DOW 13 2
في خطة شرح السيئة ، لا يتم اختبار الاستماع الفرعي. تمكنت من إعادة إنتاج الخطة السيئة عن طريق إضافة تلميح no_unnest إلى الاسم الفرعي ؛ ومع ذلك ، لم أستطع إعادة إنتاج الخطة الجيدة باستخدام تلميح غير أكثر (عند تشغيل الإجراء باستخدام تنفيذ فوري). يتم النظر في تلميحات أخرى من قبل المحسن عند استخدام تنفيذ فوري وليس التلميح غير الأكثر.
تحدث هذه المشكلة فقط عند استخدام تنفيذ فوري لاستدعاء الإجراء. إذا استخدمت تنفيذ فوري في الاستعلام نفسه ، فسيستخدم الخطة الجيدة.
المحلول 3
اتضح أن هذا خطأ معروف في أوراكل 9i. فيما يلي النص من تقرير الأخطاء.
Execute Forward يعطي خطة استعلام سيئة [ID 398605.1
Modified 09-NOV-2006 Type PROBLEM Status MODERATED
يتم تسليم هذا المستند إليك عبر عملية الرؤية السريعة (RAV) الخاصة بـ Oracle Support ، وبالتالي لم تخضع لمراجعة تقنية مستقلة.
ينطبق على:Oracle Server - Enterprise Edition - الإصدار: 9.2.0.6 يمكن أن تحدث هذه المشكلة على أي منصة.
أعراضعندما يتم تشغيل الإجراء من خلال تنفيذ الخطة المنتجة فورًا ، تختلف الخطة عن الوقت الذي يتم فيه تشغيل الإجراء مباشرة.
سببتم تحديد سبب هذه المشكلة والتحقق منها في خطأ غير منشور 2906307. ويسبب ذلك بسبب حقيقة أن بيانات SQL الصادرة من PLSQL على عمق عوافي أكبر من 1 قد تحصل على خطط تنفيذ مختلفة لأولئك الصادرة مباشرة من SQL. هناك عدة ميزات مُحسّنة تتأثر بهذا الخطأ (على سبيل المثال _UNNEST_SUBQUERY ، _PRED_MOVE_AROUND = true) قد يتم تجاهلها أيضًا.
يغطي هذا الخطأ نفس المشكلة الأساسية مثل Bug 2871645 View Complex Perging لا يحدث لعمق SQL> المتكرر 1 ولكن لميزات غير دمج العرض المعقدة.
تم إغلاق BUG 2906307 كإحداث مكررة من Bug 3182582 SQL BREATE BROON في DBMS_JOB مقارنة بـ SQL*PLUS. تم إصلاحه في 10.2
المحلوللإدراج عبارات ، استخدم تلميحًا bypass_recursive_check: insert / *+ passpass_recursive_check * / in table
مراجععلة: 2871645 - لا يحدث دمج العرض المعقد لـ SQL> DEPTH 1 BUG: 3182582 - تم تشغيل عبارة SQL PORTY في DBMS_JOB من SQL*PLUS
نصائح أخرى
لقد استخدمت بناء جملة Join http://jonathanlewis.wordpress.com/2008/03/20/ansi-sql/)
"بمجرد تشغيل التكلفة مع عدم وجود إحصائيات ، هناك كل أنواع الأشياء الصغيرة التي قد تكون كافية للتسبب في سلوك غير متوقع في خطة التنفيذ."
هناك بعض الخطوات التي يمكنك اتخاذها. الأول هو تتبع 10046.
من الناحية المثالية ، سأبدأ تتبعًا في جلسة واحدة تنفذ كل من الاستعلامات "الجيدة" و "السيئة". يجب أن يحتوي ملف التتبع على كلا الاستفسارات مع تحليل صلب. سأكون مهتمًا بالسبب في أن الثاني لديه تحليل صعب ، إذا كان له نفس بنية SQL ونفس مستخدم التحليل ، فليس هناك سبب كبير للحاجز الصعب الثاني. يجب أن تعني الجلسة نفسها أنه لا توجد شذوذات من إعدادات الذاكرة المختلفة وما إلى ذلك.
لا تظهر SQL أي استخدام للمتغيرات ، لذلك يجب ألا تكون هناك مشكلات في نوع البيانات. جميع الأعمدة "مرتبطة" باسم مستعار للجدول ، لذلك يبدو أنه لا يوجد مجال للمتغيرات المربكة والأعمدة.
الخطوة الأكثر تطرفا هي تتبع 10053. هناك مشاهد نشر على موقع جوناثان لويس. يمكن أن يسمح لك ذلك بالدخول إلى شجاعة التحسين لمحاولة تحديد سبب الاختلاف.
في المنظر الأوسع ، 9i ميت إلى حد كبير و RBO ميت إلى حد كبير. سأقوم بجدية بتقييم مشروع لنقل التطبيق إلى CBO. هناك ميزات من شأنها أن تجبر البنك المركزي العماني على استخدامها وبدون إحصائيات ستستمر هذه المشكلة في الظهور.
اتضح أن هذا خطأ معروف في أوراكل 9i. فيما يلي النص من تقرير الأخطاء.
Execute Forward يعطي خطة استعلام سيئة [ID 398605.1
تعديل 09-NOV-2006 نوع المشكلة حالة المعدل
يتم تسليم هذا المستند إليك عبر عملية الرؤية السريعة (RAV) الخاصة بـ Oracle Support ، وبالتالي لم تخضع لمراجعة تقنية مستقلة.
ينطبق على: Oracle Server - Enterprise Edition - الإصدار: 9.2.0.6 يمكن أن تحدث هذه المشكلة على أي منصة.
الأعراض عند تشغيل الإجراء من خلال تنفيذ الخطة المنتجة فورًا تختلف عن وقت تشغيل الإجراء مباشرة.
سبب تحديد سبب هذه المشكلة والتحقق منها في خطأ غير منشور 2906307. وهو سبب حقيقة أن بيانات SQL الصادرة من PLSQL على عمق عودي أكبر من 1 قد تحصل على خطط تنفيذ مختلفة لأولئك المصدرين مباشرة من SQL. هناك عدة ميزات مُحسّنة تتأثر بهذا الخطأ (على سبيل المثال _UNNEST_SUBQUERY ، _PRED_MOVE_AROUND = true) قد يتم تجاهلها أيضًا.
يغطي هذا الخطأ نفس المشكلة الأساسية مثل Bug 2871645 View Complex Perging لا يحدث لعمق SQL> المتكرر 1 ولكن لميزات غير دمج العرض المعقدة.
تم إغلاق BUG 2906307 كإحداث مكررة من Bug 3182582 SQL BREATE BROON في DBMS_JOB مقارنة بـ SQL*PLUS. تم إصلاحه في 10.2
حل لإدراج عبارات استخدام تلميح bypass_recursive_check: insert / *+ passpass_recursive_check * / in table
علة المراجع: 2871645 - لا يحدث دمج العرض المعقد لـ SQL> العمق 1 علة: 3182582 - تم تشغيل بيان SQL في DBMS_JOB من SQL*Plus