لاحظت نمط استعلامات N-per-setting أثناء التحقيق في أداء تحميل الصفحة الأولي للمستخدمين ذوي الصلاحيات الإدارية (Staff).
في موقعي، يُحمّل حساب غير إداري عادي مسار /latest بشكل ملحوظ أسرع من حسابي الإداري/ذو الصلاحيات. أثناء تحليل طلبات المستخدمين ذوي الصلاحيات باستخدام Rack Mini Profiler، وجدت أن SiteSerializer#category_types يبدو أنه يبني بيانات وصفية (metadata) لإعدادات أنواع الفئات عن طريق التحقق من كل SiteSetting على حدة لتحديد ما إذا كانت قد تم تجاوزها (overridden).
يبدو أن المسار المعني هو:
SiteSerializer#category_types
→ Categories::TypeRegistry.list
→ metadata لنوع الفئة
→ resolved_configuration_schema
→ site_setting_overridden?
→ SiteSetting.provider.find
الكود الحالي:
على وجه الخصوص، تستدعي site_setting_overridden?:
SiteSetting.provider.find(setting_name.to_sym).present?
وتستدعي resolved_configuration_schema ذلك أثناء التكرار على SiteSettings الموجودة في مخطط الإعدادات (configuration schema).
ثم تقوم SiteSettings::DbProvider#find بتنفيذ استعلام فردي للإعداد المسمّى:
في مخرجات أداة التحليل (profiler)، رأيت استعلامات فردية مثل:
SELECT name, data_type, value
FROM site_settings
WHERE name = 'discourse_post_event_allowed_on_groups';
SELECT name, data_type, value
FROM site_settings
WHERE name = 'use_local_event_date';
SELECT name, data_type, value
FROM site_settings
WHERE name = 'show_filter_by_solved_status';
SELECT name, data_type, value
FROM site_settings
WHERE name = 'topic_voting_show_who_voted';
كان هناك 16 استعلامًا يطابق نمط site_settings WHERE name = ... في الطلب الملتقط. كانت هذه الاستعلامات لأسماء إعدادات مختلفة، لذا أنا لا أقترح أن نفس البحث يتم ببساطة تكراره؛ بل يبدو أن هناك بحثًا في قاعدة البيانات واحدًا لكل SiteSetting ممثلة في مخططات إعدادات أنواع الفئات.
يبدو أن هذا ذات صلة خاصة بالمستخدمين ذوي الصلاحيات لأن category_types يُدرج فقط لهم:
أظهر تحليلي أيضًا أن إعدادات الفئات المقدمة من الإضافات تشارك في هذا المسار، بما في ذلك إعدادات Discourse Solved، والإعدادات المتعلقة بالتقويم/الأحداث، وإعدادات تصويت المواضيع (Topic Voting).
للمقارنة، على نفس تثبيت Discourse والاتصال، كان تحميل /latest الدافئ (warm) تقريبًا:
حساب إداري/ذو صلاحيات:
DOMContentLoaded: حوالي 0.77–1.03 ثانية
HTML الأولي: حوالي 2.08 ميغابايت مفككة
حساب عادي:
DOMContentLoaded: حوالي 0.51 ثانية
إجمالي الموارد المفككة: حوالي 1.50 ميغابايت
كما انتهى الأمر بتحميل PWA للحساب العادي بنفس السرعة على الأقل مقارنة بـ AMD Developer Community PWA في الاختبارات اللاحقة، لذا لا يبدو أن هذه مشكلة عامة في أداء الأصل (origin) أو CDN.
كما كان لدي طلب غير معتاد في وضع الأمان (Safe Mode) للمستخدمين ذوي الصلاحيات أنتج فيه layouts/application 1,362 استعلام SQL واستغرق حوالي 2.9 ثانية. أنا لا أعتقد أن استعلامات SiteSetting الفردية المذكورة أعلاه تفسر جميع تلك الاستعلامات، لذا أنا أتعامل مع ذلك بشكل منفصل بدلاً من الادعاء بأن هذا المسؤول عن الشذوذ بأكمله.
هل من المنطقي أن يتم جلب/تجميع حالة الإعدادات المتجاوزة المستخدمة في resolved_configuration_schema مرة واحدة، بدلاً من استدعاء SiteSetting.provider.find بشكل منفصل لكل SiteSetting؟
على سبيل المثال، تمتلك DbProvider بالفعل طريقة all، على الرغم من أنني لا أقترح أن استخدام all مباشرة هو بالضرورة التنفيذ الصحيح - فأنا أسأل بشكل رئيسي عما إذا كان تجنّب عمليات البحث في قاعدة البيانات لكل إعداد هنا يستحق الجهد.
تحققت من نفس المسار في فرع main الحالي ويبدو أن سلوك provider.find لكل إعداد لا يزال موجودًا.