Ich habe ein Muster festgestellt, das wie eine N-Queries-pro-Einstellung-Anfrage aussieht, während ich die Ladezeit der Startseite für Benutzer mit Personal-Berechtigungen untersuchte.
Auf meiner Website lädt ein normales Konto ohne Personal-Berechtigungen /latest deutlich schneller als mein Admin-/Personal-Konto. Beim Profiling der Personal-Anfrage mit Rack Mini Profiler stellte ich fest, dass SiteSerializer#category_types scheinbar die Konfigurations-Metadaten für Kategorietypen erstellt, indem jede SiteSetting einzeln daraufhin überprüft wird, ob sie überschrieben wurde.
Der relevante Pfad scheint wie folgt zu sein:
SiteSerializer#category_types
→ Categories::TypeRegistry.list
→ Kategorie-Typ metadata
→ resolved_configuration_schema
→ site_setting_overridden?
→ SiteSetting.provider.find
Aktueller Code:
Insbesondere ruft site_setting_overridden? Folgendes auf:
SiteSetting.provider.find(setting_name.to_sym).present?
und resolved_configuration_schema ruft dies auf, während es die SiteSettings im Konfigurationsschema iteriert.
SiteSettings::DbProvider#find führt dann eine individuelle Abfrage für die benannte Einstellung aus:
In der Profiler-Ausgabe sah ich individuelle Abfragen wie:
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';
In der erfassten Anfrage gab es 16 Abfragen, die diesem Muster site_settings WHERE name = ... entsprachen. Diese betrafen verschiedene Einstellungsnamen, daher schlage ich nicht vor, dass derselbe Lookup einfach nur wiederholt wird; vielmehr scheint es sich um einen Datenbank-Lookup pro SiteSetting zu handeln, die in den Konfigurationsschemas der Kategorietypen vertreten ist.
Dies scheint besonders für Benutzer mit Personal-Berechtigungen relevant zu sein, da category_types nur für Personal enthalten ist:
Mein Profiling zeigte auch, dass von Plugins bereitgestellte Kategoriekonfigurationen an diesem Pfad beteiligt waren, einschließlich Einstellungen zu Discourse Solved, kalender-/ereignisbezogenen Einstellungen und Topic Voting-Einstellungen.
Zum Vergleich war das Laden eines warmen /latest auf derselben Discourse-Installation und derselben Verbindung ungefähr:
Admin/Personal-Konto:
DOMContentLoaded: ca. 0,77–1,03 s
Initiales HTML: ca. 2,08 MB dekodiert
Normales Konto:
DOMContentLoaded: ca. 0,51 s
Gesamt dekodierte Ressourcen: ca. 1,50 MB
Die PWA des normalen Kontos lud in anschließenden Tests mindestens genauso schnell wie die PWA der AMD Developer Community, daher scheint dies kein allgemeines Problem mit der Leistung des Origins/CDN zu sein.
Ich hatte auch eine ungewöhnliche Personal-Safe-Mode-Anfrage, bei der layouts/application 1.362 SQL-Abfragen erzeugte und etwa 2,9 Sekunden dauerte. Ich glaube nicht, dass die oben genannten Abfragen pro SiteSetting für alle diese Abfragen verantwortlich sind, daher behandle ich dies getrennt und behaupte nicht, dass dies für den gesamten Ausreißer verantwortlich ist.
Würte es Sinn ergeben, den Status der überschriebenen Einstellungen, der von resolved_configuration_schema verwendet wird, einmalig abzurufen/zu bündeln, anstatt SiteSetting.provider.find für jede SiteSetting separat aufzurufen?
Zum Beispiel hat DbProvider bereits eine all-Methode, obwohl ich nicht vorschlage, dass die direkte Verwendung von all unbedingt die richtige Implementierung ist – ich frage mich hauptsächlich, ob es sich lohnen würde, die Datenbank-Lookups pro Einstellung hier zu vermeiden.
Ich habe denselben Pfad im aktuellen main überprüft und es scheint, dass das Verhalten des pro-Einstellung-provider.find weiterhin vorhanden ist.