سؤال

لدي استعلام SQL يبدو كالتالي:

SELECT * FROM(
    SELECT
        ...,
        row_number() OVER(ORDER BY ID) rn
    FROM
        ...
) WHERE rn between :start and :end

في الأساس، إن الجزء ORDER BY هو الذي يبطئ الأمور.إذا قمت بإزالته، فإن تكلفة EXPLAIN تنخفض بمقدار حجم (أكثر من 1000x).لقد حاولت هذا:

SELECT 
    ...
FROM
    ...
WHERE
    rownum between :start and :end

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

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

المحلول

ROW_NUMBER غير فعال إلى حد كبير في Oracle.

راجع المقالة في مدونتي للحصول على تفاصيل الأداء:

بالنسبة لاستفسارك المحدد، أنصحك باستبداله بـ ROWNUM وتأكد من استخدام الفهرس:

SELECT  *
FROM    (
        SELECT  /*+ INDEX_ASC(t index_on_column) NOPARALLEL_INDEX(t index_on_column) */
                t.*, ROWNUM AS rn
        FROM    table t
        ORDER BY
                column
        )
WHERE rn >= :start
      AND rownum <= :end - :start + 1

سوف يستخدم هذا الاستعلام COUNT STOPKEY

تأكد أيضًا من ذلك column ليست لاغية، أو إضافة WHERE column IS NOT NULL حالة.

وإلا فلا يمكن استخدام الفهرس لاسترداد كافة القيم.

لاحظ أنه لا يمكنك استخدام ROWNUM BETWEEN :start and :end بدون استعلام فرعي.

ROWNUM يتم دائمًا تعيينه أخيرًا والتحقق منه أخيرًا، بهذه الطريقة ROWNUMتأتي دائمًا بالترتيب دون ثغرات.

إذا كنت تستخدم ROWNUM BETWEEN 10 and 20, ، الصف الأول الذي يستوفي جميع الشروط الأخرى سيصبح مرشحاً للعودة، ومخصصاً له مؤقتاً ROWNUM = 1 وفشل في اختبار ROWNUM BETWEEN 10 AND 20.

ثم سيكون الصف التالي مرشحًا تم تعيينه له ROWNUM = 1 والفشل، وما إلى ذلك، لذلك، أخيرًا، لن يتم إرجاع أي صفوف على الإطلاق.

ينبغي حل هذا عن طريق وضع ROWNUMفي الاستعلام الفرعي.

نصائح أخرى

ويبدو استعلام ترقيم الصفحات لي.

ومن هذه المادة ASKTOM (حوالي 90٪ إلى أسفل الصفحة):

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

وأيضا الاستفسارات الخاصة بك حيث لا قرب نفسه لذلك أنا لست متأكدا ما الفائدة من مقارنة تكاليف واحدة إلى أخرى هي.

هل ORDER BY بك العمود فهرستها؟ إن لم يكن هذا هو مكان جيد للبدء.

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

وباختصار، وهذا هو الكثير من العمل، وهذا هو السبب محسن يعطيها التكلفة العالية.

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

إذا كنت تظهر المستخدم النهائي 10 البنود في وقت واحد، قد يكون من المفيد فعلا الاستيلاء على 100 شركة من DB، ثم بعد نهاية الشوط الاول التطبيق أن 100 إلى عشر قطع.

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

واستفسارك عن لا معنى له بالنسبة لي. الاستعلام عن أكثر من ROWID يبدو وكأنه يسأل عن المتاعب. ليس هناك معلومات ذات العلاقة في هذا الاستعلام. هو الاستعلام الحقيقي الذي كنت تواجه مشكلة مع أو المثال أن تتكون لتوضيح مشكلتك؟

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