استخدام will_paginate بدون:total_entries لتحسين الاستعلام المطول

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

سؤال

لدي التنفيذ الحالي ل will_paginate الذي يستخدم paginate_by_sql طريقة بناء المجموعة المراد ترقيم صفحاتها.لدينا استعلام مخصص ل Total_entries هذا معقد للغاية ويضع عبئًا كبيرًا على قاعدة بياناتنا.لذلك نود قطع Total_entries من الصفحات تمامًا.

بمعنى آخر، بدلاً من عرض ترقيم الصفحات النموذجي لـ "السابق 1 [2] 3 4 5 التالي"، نود ببساطة استخدام الزر "التالي - السابق" فقط.ولكن علينا أن نعرف بعض الأشياء.

  1. هل نعرض الرابط السابق؟لن يحدث هذا إلا بالطبع إذا كانت السجلات الموجودة قبل تلك المعروضة في التحديد الحالي
  2. هل نعرض الرابط التالي؟لن يتم عرض هذا إذا تم عرض السجل الأخير في المجموعة

من مستندات

سيتم إنشاء استعلام لحساب الصفوف تلقائيًا إذا لم تقم بتوفير: Total_entries.إذا واجهت مشاكل مع SQL التي تم إنشاؤها ، فقد ترغب في أداء العد يدويًا في التطبيق الخاص بك.

لذا فإن الوضع المثالي في النهاية هو ما يلي.

  • قم بإزالة عدد Total_entries لأنه يسبب تحميلًا كبيرًا على قاعدة البيانات
  • عرض 50 سجلاً في المرة الواحدة مع نصف صفحات باستخدام الأزرار التالية/السابقة فقط للتنقل دون الحاجة إلى عرض جميع أرقام الصفحات المتاحة
  • قم بعرض الزر التالي والزر السابق فقط وفقًا لذلك

هل عمل أي شخص مع مشكلة مماثلة أو لديه أفكار حول حل؟

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

المحلول

هناك العديد من المناسبات التي يؤدي فيها will_paginate مهمة فظيعة حقًا في حساب عدد الإدخالات، خاصة إذا كانت هناك صلات متضمنة تربك منشئ عدد SQL.

إذا كان كل ما تحتاجه هو طريقة بسيطة للسابق/التالي، فكل ما عليك فعله هو محاولة استرداد إدخالات N+1 من قاعدة البيانات، وإذا حصلت على N فقط أو أقل مما كنت عليه في الصفحة الأخيرة.

على سبيل المثال:

per_page = 10
page = 2

@entries = Thing.with_some_scope.find(:all, :limit => per_page + 1, :offset => (page - 1) * per_page)

@next_page = @entries.slice!(per_page, 1)
@prev_page = page > 1

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

لقد وجدت أن هذا يعمل بشكل أفضل بكثير من الطريقة الافتراضية will_paginate.

مشكلة الأداء الوحيدة هي وجود قيود على MySQL والتي قد تمثل مشكلة اعتمادًا على حجم الجداول الخاصة بك.

لأي سبب من الأسباب، فإن مقدار الوقت الذي يستغرقه تنفيذ استعلام بحد صغير في MySQL يتناسب مع الإزاحة.في الواقع، يقرأ محرك قاعدة البيانات جميع الصفوف المؤدية إلى قيمة الإزاحة المحددة، ثم يقوم بإرجاع عدد LIMIT من صفوف الأرقام التالية، دون التخطي للأمام كما تتوقع.

بالنسبة لمجموعات البيانات الكبيرة، حيث يكون لديك قيم OFFSET في نطاق 100000 زائد، قد تجد أن الأداء يتدهور بشكل كبير.كيف سيظهر ذلك هو أن تحميل الصفحة 1 سريع جدًا، والصفحة 1000 بطيئة إلى حد ما، ولكن الصفحة 2000 بطيئة للغاية.

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