craftcms / craftcms/cms

[5.x]: Asset::getSrcset takes too many database queries

Offen
#17,653 5 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
PHP
Sterne
3.6k
Forks
705
Ø Merge
1 T. 5 Std.
Gemergte PRs (30 T.)
134

Beschreibung

What happened?
Description

I'm investigating some performance issues with the MySQL server, so I'm trying to reduce the number of database queries required for a page load, especially on a cold cache, because that's where most of the problems occur.

I found that the single largest source for the query count is Asset::getSrcset(). This uses a separate database query for every single size. In fact, I found that every single size takes two database queries. With 5 transforms in two formats (WebP and AVIF), we get 20 database queries for a single image! And that's just for the srcset, there are additional queries for the base transform.

Steps to reproduce
  1. Where image is an Asset, use image.getSrcset([240, 360, 480, 600, 720, 840, 960]) and watch the number of database queries in the debug panel as the number of sizes is increased.
Expected behavior

Asset::getSrcset() should group its queries to avoid the N+1 (or rather, N+2) problem here. All transforms should be loaded in a single query, adding more sizes should not result in additional database queries for each one.

Actual behavior

The number of database queries grows exponentially at an alarming rate with the number of images on a page, and transforms per image.

Craft CMS version

5.8.6

PHP version

8.3

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne bei Asset::getSrcset() und reproduziere das Problem mit den aufgeführten Größen, während du die Anzahl der Datenbankabfragen im Debug-Panel beobachtest. Verfolge, wie jede Transform-Größe geladen wird, und überprüfe anschließend, dass alle Transforms in einer einzigen Abfrage geladen werden und dass das Hinzufügen von Größen nicht mehr für jede Größe Abfragen hinzufügt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
mysql, php
Bereich
backend, databases, performance
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.