سؤال

الوضع

لدي بعض المشاكل مع تنفيذ الاستعلام خطة متوسطة الحجم الاستعلام على كمية كبيرة من البيانات في أوراكل 11.2.0.2.0.من أجل تسريع الأمور ، قدمت مجموعة مرشح أن لا يقرب شيئا من هذا القبيل:

PROCEDURE DO_STUFF(
    org_from VARCHAR2 := NULL,
    org_to   VARCHAR2 := NULL)

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((org_from IS NULL) OR (org_from <= org.no))
   AND ((org_to   IS NULL) OR (org_to   >= org.no)))
  -- [...]

كما ترون, كنت ترغب في تقييد JOIN من organisations باستخدام اختياري مجموعة من منظمة أرقام.رمز العميل يمكن أن نطلق DO_STUFF مع (من المفترض أن تكون سريع) أو بدون (بطيء جدا) تقييد.

المشكلة

المشكلة هي, PL/SQL سيتم إنشاء ربط المتغيرات المذكورة أعلاه org_from و org_to المعلمات ، وهو ما أتوقع في معظم الحالات:

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((:B1 IS NULL) OR (:B1 <= org.no))
   AND ((:B2 IS NULL) OR (:B2 >= org.no)))
  -- [...]

الحل

فقط في هذه الحالة قمت بقياس خطة تنفيذ الاستعلام أن يكون أفضل بكثير عندما كنت مجرد مضمنة القيم ، أيعند الاستعلام المنفذة من قبل شركة أوراكل هو في الواقع شيء مثل

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((10 IS NULL) OR (10 <= org.no))
   AND ((20 IS NULL) OR (20 >= org.no)))
  -- [...]

"الكثير" ، أعني 5-10x أسرع.لاحظ أن الاستعلام يتم تنفيذ نادرا جدا ، أيمرة واحدة في الشهر.لذلك أنا لا تحتاج إلى ذاكرة التخزين المؤقت خطة التنفيذ.

أسئلتي

  • كيف يمكنني مضمنة القيم في PL/SQL ؟ أنا أعرف عن تنفيذ فوري, ولكن أنا أفضل أن يكون PL/SQL تجميع الاستعلام بلدي و لا سلسلة سلسلة.

  • هل أنا فقط لقياس ما حدث عن طريق الصدفة أو يمكن أن أفترض أن inlining المتغيرات هو في الواقع أفضل (في هذه الحالة)?السبب أنا أسأل لأنني أعتقد أن ربط متغيرات القوة أوراكل وضع العامة خطة التنفيذ ، بينما inlined القيم من شأنها أن تسمح لتحليل محددة جدا عمود إحصاءات مؤشر.حتى أستطيع أن أتخيل أن هذا ليس مجرد صدفة.

  • أنا في عداد المفقودين شيئا ؟ ربما هناك تماما طريقة أخرى لتحقيق خطة تنفيذ الاستعلام تحسين عدا متغير inlining (ملاحظة لقد حاولت عدد قليل من تلميحات كذلك ولكن أنا لست خبير في هذا المجال)?

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

المحلول

في واحد من التعليقات الخاصة بك قلت:

"كما راجعت مختلف ربط القيم.مع ربط المتغيرات أحصل على بعض الكامل طاولة الفحص, بينما الثابت تلوينها القيم الخطة تبدو أفضل كثيرا."

هناك نوعان من المسارات.إذا كنت تمر في لاغية للمعلمات ثم يتم اختيار جميع السجلات.في ظل هذه الظروف الجدول الكامل المسح الضوئي هي الطريقة الأكثر فعالية من استرجاع البيانات.إذا كنت تمر في القيم ثم فهرستها يقرأ قد تكون أكثر كفاءة لأنك فقط اختيار مجموعة فرعية صغيرة من المعلومات.

عند صياغة الاستعلام باستخدام ربط المتغيرات محسن أن تتخذ قرارا:يجب أن نفترض أن معظم الوقت سوف تمر في القيم أو أنك سوف تمر في القيم الخالية?من الصعب.حتى ننظر في الأمر بطريقة أخرى:هو أكثر كفاءة للقيام الجدول الكامل المسح الضوئي عندما تحتاج فقط لتحديد مجموعة فرعية من السجلات أو فهرستها يقرأ عندما كنت في حاجة لتحديد كافة السجلات ؟

يبدو كما لو أن محسن قد قطنية على الجدول الكامل بفحص بأنها أقل كفاءة العملية لتغطية كل الاحتمالات.

في حين عندما كنت رمز القرص الثابت القيم محسن يعرف على الفور أن 10 IS NULL يقيم إلى FALSE ، لذلك يمكن أن تزن مزايا استخدام فهرسة يقرأ من أجل العثور على المطلوب الفرعية مجموعة السجلات.


لذا ماذا تفعل ؟ كما تقول هذا الاستعلام هو فقط تشغيل مرة واحدة في الشهر أعتقد أنه لا يتطلب سوى تغيير طفيف على العمليات التجارية منفصلة الاستفسارات:واحد لجميع المنظمات واحد مجموعة فرعية من المنظمات.


"راجع للشغل, إزالة :R1 باطل شرط لا يغير من خطة التنفيذ كثيرا ما يترك لي مع الآخر جانب من أو شرط،: R1 <= org.حيث لا فارغة لا معنى له على أي حال, كما org.لا ليست فارغة"

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

WHERE org.id BETWEEN 10 AND 11

...في حين أن هذا من المرجح أن تكون أكثر تركيبها على كامل مسح الطاولة...

WHERE org.id BETWEEN 10 AND 1199999

هذا هو المكان الذي ربط متغير الطفولية يأتي دور.

(اعتمادا على توزيع القيم ، بالطبع).

نصائح أخرى

منذ خطط الاستعلام هي في الواقع باستمرار مختلفة ، وهذا يعني أن محسن هو أصل التقديرات الخروج لسبب ما.يمكنك التأكد من خطط الاستعلام أن محسن تتوقع شروط الكافي انتقائية عند ربط المتغيرات المستخدمة ؟ منذ كنت تستخدم 11.2, Oracle يجب أن يكون استخدام التكيف المؤشر المشاركة لذلك ينبغي أن لا يكون هناك ربط متغير الطفولية المسألة (على افتراض أنك تدعو النسخة مع ربط المتغيرات مرات عديدة مع مختلف NO القيم في الاختبار الخاص بك.

هي أصل تقديرات خطة جيدة فعلا صحيح ؟ أنا أعلم أنك قلت أن الإحصاءات على NO عمود دقيقة ولكن أود أن تكون مشبوهة من الضالة الرسم البياني الذي قد لا يتم تحديث الخاص بك العادية وجمع الإحصاءات العملية ، على سبيل المثال.

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

واحد اختبار إضافي في محاولة ، ومع ذلك ، سيكون محل SQL 99 الانضمام إلى الجملة مع أوراكل القديم جملة ، أي

SELECT <<something>>
  FROM <<some other table>> cust,
       organization org
 WHERE cust.org_id = org.id
   AND (    ((org_from IS NULL) OR (org_from <= org.no)) 
        AND ((org_to   IS NULL) OR (org_to   >= org.no)))

ومن الواضح أن هذا لا يغير أي شيء ، ولكن كانت هناك محلل القضايا مع SQL 99 جملة ذلك أن ما تحقق.

رائحتها مثل ربط الطفولية, ولكن أنا فقط على أوراكل 10, لذلك أنا لا يمكن أن يدعي نفس المشكلة موجودة في 11.

هذا يبدو كثيرا مثل الحاجة إلى التكيف المؤشر تقاسم ، جنبا إلى جنب مع SQLPlan الاستقرار.أعتقد أن ما يحدث هو أن capture_sql_plan_baselines parameter is true.والشيء نفسه بالنسبة use_sql_plan_baselines.إذا كان هذا صحيحا التالية يحدث:

  1. المرة الأولى التي استعلام بدأ تحليل, فإنه يحصل خطة جديدة.
  2. المرة الثانية هذه الخطة يتم تخزينها في sql_plan_baselines حسب خطة مقبولة.
  3. كل بعد تشغيل هذا الاستعلام استخدام هذه الخطة ، بغض النظر عما ربط المتغيرات.

إذا التكيف المؤشر مشاركة نشطة بالفعل ، محسن توليد جديدة/أفضل خطة تخزينه في sql_plan_baselines ولكن ليس قادرا على استخدامها ، حتى شخص يقبل هذا أحدث خطة مقبولة خطة بديلة.تحقق dba_sql_plan_baselines ومعرفة ما إذا كان الاستعلام يحتوي على إدخالات مع accepted = 'NO' and verified = null يمكنك استخدام dbms_spm.evolve أن تتطور الخطة الجديدة ويكون ذلك تلقائيا مقبولة إذا كان أداء الخطة على الأقل 1,5 مرات أفضل من دون خطة جديدة.

آمل أن يساعد هذا.

أضفت هذا التعليق ، ولكن سوف نقدم هنا كذلك.نأمل أن هذه ليست مفرطة في التبسيط ، والنظر في ردود مفصلة قد يكون سوء فهم المشكلة بالضبط, لكن على أي حال...

وقالت المنظمات في الجدول عمود رقم (org.لا) أن يعرف عدد.في ضمنية ، أرقام أن لا يقارن.

JOIN organisations org
    ON (cust.org_id = org.id
   AND ((10 IS NULL) OR (10 <= org.no))
   AND ((20 IS NULL) OR (20 >= org.no)))

في الإجراء الخاص بك, كنت تمر في varchar2:

PROCEDURE DO_STUFF(
    org_from VARCHAR2 := NULL,
    org_to   VARCHAR2 := NULL)

حتى مقارنة varchar2 إلى العدد ، أوراكل سوف تضطر إلى القيام التحويلات, لذا هذا قد يسبب بمسح كامل.

الحل: تغيير proc لتمرير في أرقام

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