WooCommerce Analytics läuft auf einer columnar Kopie bis zu 83-mal schneller
WooCommerce Analytics lief in von Percona durchgeführten Benchmarks auf einer columnar replica einer analytical database bis zu 83-mal schneller als auf einer transactional storage engine. Dies zeigt den möglichen Vorteil, analytische Berichte von der Transaktionsdatenbank eines Onlineshops zu trennen. Die größten Steigerungen zeigten sich bei Berichten, die Bestellungen sowohl nach Zeit als auch nach Produktkategorie gruppierten, allerdings bestehen weiterhin wichtige Unterschiede bei Kompatibilität und Genauigkeit.
Der grundlegende Unterschied liegt darin, wie die jeweilige Engine Daten anordnet. Die transactional storage engine ist row-oriented, das heißt, sie speichert die zu einem record gehörenden Werte zusammen. Das eignet sich für Online Transaction Processing (OLTP), also die kurzen Lese- und Schreibvorgänge bei Aktivitäten wie dem Aufgeben einer Bestellung. Online Analytical Processing (OLAP) durchsucht, gruppiert und fasst dagegen große Mengen von records zusammen. Eine columnar Engine speichert jedes Feld separat, sodass ein Bericht nur die benötigten Spalten lesen, ähnliche Werte effektiver komprimieren und Daten stapelweise verarbeiten kann.
Bei der analytical database handelt es sich um ein portables System, dessen Ansatz mit einer leichtgewichtigen eingebetteten relationalen Datenbank vergleichbar ist. Implementierungen eines von der Community entwickelten Datenbankprojekts und von Alibaba haben es ermöglicht, die analytical database als storage engine für den Open-Source-Datenbankserver zu verwenden. Eine für die analytical engine deklarierte Tabelle wird dadurch in columnar Form gespeichert. Eine vorgeschlagene Architektur belässt den laufenden Shop auf der transactional storage engine und verwendet asynchronous replication vom Open-Source-Datenbankserver, der Datenbankänderungen fortlaufend kopiert, um eine analytische replica für Berichte aktuell zu halten.
Percona testete dieses Design mit WooCommerce, das nach Angaben des Unternehmens von rund vier Millionen Shops und von 20 bis 39 % der E-Commerce-Websites genutzt wird. Der erzeugte Testshop enthielt 400.000 Bestellungen und 5.000 Produkte, die mit dem Plugin WooCommerce Smooth Generator geladen wurden. WooCommerce vermeidet es normalerweise, Berichte direkt aus laufenden Bestellungen zu erstellen. Es unterhält sieben denormalisierte Lookup-Tabellen sowie seine Tabelle mit Bestellstatistiken, eine Tabelle mit einer Zeile pro Bestellung, die Datumsangaben, Status, Kunden, Artikelanzahlen und Geldsummen enthält. Ein geplanter Hintergrundprozess muss diese abgeleiteten Daten aktuell halten.
Beide Datenbanken liefen in Docker-Containern auf demselben Host. Die Quelle verwendete Perconas Distribution des Open-Source-Datenbankservers in Version 8.0.46 mit der transactional storage engine und einem buffer pool von 4 GiB. Die replica verwendete Version 8.0.44-2 von Alibabas Branch desselben Servers, basierend auf der Upstream-Version 8.0.44 und zum Testzeitpunkt die neueste verfügbare Version. Das Speicherlimit der analytical database betrug 4 GiB, ihre Thread-Einstellung nutzte alle CPU-Kerne des Systems, und eine Einstellung zur erzwungenen Konvertierung wandelte Tabellen, die über replication oder das Dump-Dienstprogramm des Servers erstellt wurden, von der transactional engine in die analytical engine um. Das Verzeichnis der Transaktionsdatenbank belegte 7,3 GiB, während die analytische Kopie 601 MiB und damit ungefähr ein Zwölftel des Speicherplatzes beanspruchte.
WooCommerce stellte eine Hürde beim Routing dar, weil WordPress sowohl für Shop-Aktivitäten als auch für Analytics eine einzige globale Datenbankverbindung verwendet. Percona kopierte deshalb die gesamte WooCommerce-Installation in ein anderes Verzeichnis, änderte ausschließlich ihren Datenbank-Host und verband diese Kopie mit der replica. Sie erhielt einen separaten PHP-Pool, socket und virtual host auf einem internen port. Anfragen an die normale Installation erreichten die transactional storage engine, während Anfragen an die kopierte Installation denselben Anwendungscode gegen die analytical database ausführten.
Für jeden Bericht unternahm Percona mehrere Versuche und behielt das schnellste Ergebnis. Die Engines liefen nicht gleichzeitig: Jeder Bericht wurde zunächst auf der transactional storage engine und anschließend auf der analytical database ausgeführt. Die Ergebnisse wurden serialisiert, sortiert und verglichen, bevor die Zeitmessung akzeptiert wurde. Die Anfragen liefen über die Analytics REST API von WooCommerce mit erzwungenem cache refresh, wodurch die Datenbank jede Antwort berechnen musste, statt eine zwischengespeicherte Antwort zurückzugeben. Abfragen mit einer für den Quelldatenbankserver spezifischen Syntax, die auf der analytical database fehlschlugen, wurden ausgeschlossen und nicht angepasst.
Die integrierten Berichte deckten den Zeitraum vom 1. Januar 2024 bis zum 1. September 2026 ab. Statistische Berichte gruppierten die Ergebnisse nach Monat, während Detailberichte höchstens 100 Zeilen pro Seite zurückgaben. Jeder akzeptierte integrierte Bericht war auf der analytical database schneller, wobei die Verbesserungen vom ungefähr Zehnfachen bis zum fast 63-Fachen reichten. Die analytical database schloss sie in weniger als einer Sekunde ab, gegenüber fünf bis 16 Sekunden auf der transactional storage engine. Kategorieberichte erzielten aufgrund ihrer umfangreichen Gruppierung und Aggregation die größten Verbesserungen.
Segmentierte Berichte, die Summen nach Stunde, Tag, Woche oder Monat aufteilen und zusätzlich nach Dimensionen wie der Kategorie unterteilen können, vergrößerten den Unterschied. Die analytical database war etwa 14- bis 83-mal schneller. Die Segmentierung nach Kategorie und Zeit führte bei der transactional storage engine zu Ausführungszeiten von mehreren Minuten, während die analytical database innerhalb von Sekunden antwortete. Percona testete außerdem alle elf Berichte des Plugins Customer Analytics for WooCommerce von Coddium, darunter Lifetime Value, Churn, RFM Segments, Cohort Retention, Repeat Purchases, Order Sequence und Acquisition Sources. Ohne Änderungen am Plugin war die analytical database etwa zwei- bis fast 70-mal schneller.
Eine direkte Abfrage der Tabellen mit laufenden Bestellungen zählte Artikel nach Produktkategorie, Rechnungsort und Wochentag. Bei jeweils drei Versuchen pro Engine benötigte die analytical database konstant etwa 4,1 Sekunden, während die transactional storage engine ungefähr vier Minuten und 16 Sekunden brauchte. Das Ergebnis enthielt auf der analytical database zwei zusätzliche Gruppen, weil die Engines Text unterschiedlich behandelten. Die transactional engine verwendete die Groß-/Kleinschreibung und Akzente ignorierende collation der Ortsspalte, also die Regeln zum Vergleichen und Sortieren von Text. Die analytical database verglich dagegen die zugrunde liegenden Bytes und behandelte Schreibweisen mit und ohne Akzent getrennt. Es wurden keine Bestellungen ausgelassen.
Dieses Verhalten ist eine von mehreren Einschränkungen bei der Bereitstellung. Syntax der Quelldatenbank, etwa das Casting eines Werts als unsigned integer type, kann fehlschlagen, weil die analytical database den Typ nicht erkennt. Abfragen müssen möglicherweise umgeschrieben werden, potenziell über einen query-rewriting proxy oder das rewrite plugin des Datenbankservers. Das Gruppieren und Verknüpfen anhand numerischer identifiers statt anhand von Text kann Unterschiede bei der collation verringern. Ein Test unterschiedlicher Orte ergab auf der analytical database 114.412 Werte und auf der transactional storage engine 114.375 Werte. Das Erzwingen eines binären Vergleichs auf der transactional engine ergab ebenfalls 114.412.
Die analytical database berechnete Dezimalzahlen außerdem standardmäßig als double-precision floating point. Deshalb unterschieden sich einige Berichtssummen um weniger als einen Cent. Percona hielt diese Genauigkeit für Berichte für ausreichend, wies jedoch auf das Problem bei Berechnungen mit echtem Geld hin.