سؤال

فجأة (لكن لسوء الحظ ، لا أعرف متى كانت "فجأة" ؛ أعلم أنها كانت على ما يرام في مرحلة ما في الماضي) بدأت إحدى استفساراتي تستغرق 7+ ثوان بدلاً من ميلي ثانية لتنفيذها. لدي طاولة محلية واحدة و 3 جداول يتم الوصول إليها عبر رابط DB. يتم ربط الجداول البعيدة الثلاثة معًا ، وينضم إلى طاولتي المحلية.

الطاولة المحلية حيث تستغرق الشرط فقط بضعة ميليس لتنفيذها من تلقاء نفسها ، ولا تعيد سوى عدد قليل من السجلات (10 أو 100 على الأكثر). تحتوي الجداول الثلاثة البعيدة على مئات الآلاف ، وربما الملايين ، من السجلات بينهما ، وإذا انضممت إليهم بشكل مناسب ، أحصل على عشرات أو مئات الآلاف من السجلات.

أنا فقط الانضمام إلى الجداول البعيدة حتى أتمكن من سحب بضع أجزاء من البيانات المتعلقة بكل سجل في الجدول المحلي الخاص بي.

ومع ذلك ، فإن ما يبدو أنه يحدث هو أن Oracle ينضم إلى الجداول البعيدة معًا أولاً ثم طاولتي المحلية لتلك الفوضى في النهاية. ستكون هذه فكرة سيئة دائمًا ، خاصةً بالنظر إلى مجموعة البيانات الموجودة الآن ، لذلك أضفت أ /*+ LEADING(local_tab remote_tab_1) */ تلميح إلى استفساري ويعود الآن بالميلي ثانية.

قارنت الخطط الشرح وهي متطابقة تقريبًا ، باستثناء واحدة BUFFER SORT على أحد الجداول البعيدة.

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

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

المحلول

عند اختيار خطة التنفيذ ، تقدر Oracle تكاليف الخطط المختلفة. واحدة من المعلومات الحاسمة لهذا التقدير هي أن يتم إرجاع مقدار الصفوف من خطوة من خطة التنفيذ. يحاول Oracle تقدير أولئك الذين يستخدمون "إحصائيات" ، أي معلومات حول عدد الصفوف التي يحتوي عليها الجدول ، وعدد القيم المختلفة التي يحتوي عليها العمود ؛ كيف يتم توزيع هذه القيم بالتساوي.

هذه الإحصائيات هي مجرد إحصائيات ، وقد تكون خاطئة ، والتي تعد واحدة من أهم الأسباب لسوء الحكم على OpenSizer.

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

نصائح أخرى

المشكلة الشائعة التي صادفتها هي استعلام ينضم إلى العديد من الجداول ، حيث تشكل الوصلات سلسلة من طرف إلى آخر ، على سبيل المثال:

SELECT *
FROM   tableA, tableB, tableC, tableD, tableE
WHERE  tableA.ID0 = :bind1
AND    tableA.ID1 = tableB.ID1
AND    tableB.ID2 = tableC.ID2
AND    tableC.ID3 = tableD.ID3
AND    tableD.ID4 = tableE.ID4
AND    tableE.ID5 = :bind2;

لاحظ كيف يمكن أن يختار المحسن قيادة الاستعلام من Tablea (على سبيل المثال إذا كان الفهرس على ID0 انتقائيًا بشكل جيد) أو من Tablee (إذا كان الفهرس على Tablee.id5 أكثر انتقائية).

قد تتسبب الإحصائيات في الجداول في الاختيار بين هاتين الخطتين لتحقيق التوازن على حافة السكين ؛ في يوم من الأيام تعمل بشكل جيد (القيادة من Tablea) ، يتم جمع إحصائيات جديدة في اليوم التالي ، وفجأة الخطة البديلة التي تقود من Tablee لها تكلفة أقل ويتم اختيارها.

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

أنت تقوم بتحسين الاستعلام الموزعة ، وهذا وحش صعب. قد تكون إحصائيات الجدول الخاصة بك حاليًا ، ولكن الآن الجداول الموجودة في النظام البعيد غير متوقفة أو تغيرت. أو فهارس النظام عن بُعد/إزالته/تعديله ، وهذا كسر خطتك. (هذا سبب ممتاز للنظر في النسخ المتماثل - حتى تتمكن من التحكم في الفهارس والإحصاءات ضدها).

ومع ذلك ، فإن تقدير أوراكل للكسر هو سائق أساسي في خطة التنفيذ. يمكن أن يساعد تحليل تتبع 10053 (كتاب Oracle Stationsals القائم على التكلفة من جوناثان لويس أمثلة رائعة من 8i إلى 10.1) LEADING تلميح إصلاحه.

ال DRIVING_SITE قد تكون تلميح خيارًا أفضل إذا كنت تعلم أنك تريد دائمًا انضمام الجداول المحلية أولاً قبل متابعة الموقع البعيد ؛ يوضح نيتك دون قيادة الخطة بالطريقة أ LEADING تلميح.

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

كان ذلك قبل بضع سنوات. لقد وثقت تحليلي في ذلك الوقت هنا.

ري ،

من الصعب التأكد من سبب مشاكل الأداء دون رؤية SQL.

عندما كان استعلام Oracle أداءً جيدًا قبل ذلك ، ويبدأ فجأة في الأداء بشكل سيء ، فإنه يرتبط عادةً بواحدة من مشكلتين:

أ) الإحصائيات قديمة. هذا هو أسهل وأسرع ما يمكن التحقق منه ، حتى لو كان لديك عملية دفعة من التدبير المنزلي من المفترض أن تعتني بها ... تحقق دائمًا.

ب) تغيير حجم البيانات / نمط البيانات.

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

تلميحات هشة بشكل سيء ، لأن أوراكل لا يلتزم باتباع التلميح. عندما يتغير حجم البيانات أو النمط أكثر من ذلك ، قد يتجاهل Oracle التلميح ويفعل ما يعتقد أنه الأفضل (أي الأسوأ ؛-).

إذا لم تتمكن من وضع هذه الجداول في قاعدة بيانات واحدة ، فإنني أوصيك بالتطلع إلى تقسيم استعلامك إلى بيانين:

  1. أدخل على Sub-Select لنسخ البيانات الخارجية إلى جدول مؤقت عالمي في قاعدة البيانات الحالية الخاصة بك.
  2. اختر من الجدول المؤقت العالمي للانضمام إلى طاولتك الأخرى.

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

إن النفقات العامة لـ Oracle لإنشاء جدول جديد بالكامل ، أو إدراج مجموعة من السجلات ، أصغر بكثير مما يتوقعه معظم الناس. تحديد الجدول المؤقت العالمي يقلل من ذلك النفقات العامة.

ماثيو

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