Zusammenfassung
Der TYPO3 DataHandler ist das wichtigste Werkzeug für Daten im System. (\TYPO3\CMS\Core\DataHandling\DataHandler).
Er speichert alle Daten im Hintergrund.
Sein Aufbau achtet sehr stark auf die Sicherheit und die Richtigkeit der Daten.
Das kostet aber viel Leistung bei sehr vielen Daten.
Wir messen in diesem Text die Leistung beim Import von 10.000 Einträgen.
Einträge nennt man in TYPO3 auch Records.
Wir zeigen Ihnen gute Wege für eine deutlich bessere Leistung.
Das ist unser Ergebnis: Sie verarbeiten die Daten am besten in kleinen Paketen. Das nennt man auch Paketverarbeitung. Sie schalten zudem unwichtige Funktionen im Code aus. So machen Sie die Leistung um über 90 Prozent besser. Die Dauer der Ausführung sinkt von 412 Sekunden auf unter 39 Sekunden.
Inhaltsverzeichnis
Der TYPO3 DataHandler: Analyse vom Aufbau
Der DataHandler ist nicht für eine extrem schnelle Verarbeitung gebaut. Er ist der strenge Wächter für alle Änderungen an Daten im System. Dieser Aufbau hat große Folgen für die Leistung.
Das Wächter-Prinzip
Der DataHandler ist der einzige Weg für das Speichern von Daten. Das gilt für alle Tabellen mit einem TCA. TCA ist eine wichtige Steuerungsdatei in TYPO3. Diese strenge Prüfung garantiert immer fehlerfreie Daten im ganzen System. Aber sie erzeugt auch sehr viel extra Arbeit bei jeder einzelnen Aufgabe:
- Prüfung von Rechten: Das System prüft die Rechte der Benutzer. Es prüft den Zugriff auf Seiten und Einträge.
- TCA-Regeln: Das System beachtet alle Regeln aus dem TCA. Es wandelt Daten um und prüft alle Verbindungen.
- Versionen und Verlauf: Das System erstellt einen Verlauf der Änderungen. Es baut Versionen für den Arbeitsbereich.
- Protokoll im System: Das System speichert jede Aufgabe in einem Protokoll. Die Tabelle dafür heißt
sys_log. - Erweiterungen: Das System ruft zusätzliche Funktionen auf. Das nennt man Hooks oder Events. Das kostet oft viel Leistung.
- Zwischenspeicher: Das System leert den Zwischenspeicher nach jeder Änderung. Dieser Speicher heißt auch Cache. Das braucht bei vielen Einträgen extrem viel Kraft.
Das Problem mit dem gemerkten Zustand
Die Anleitung von TYPO3 sagt ganz klar: Der DataHandler merkt sich seinen Zustand. Das nennt man auch "stateful". Sie müssen den DataHandler für jede neue Aufgabe komplett neu erstellen. Sie dürfen ihn nicht für viele verschiedene Aufgaben am Stück wiederverwenden. Das führt sonst zu großen Fehlern.
Ein DataHandler sammelt bei der Arbeit viele Daten an. Er merkt sich alle Fehler und Verbindungen zu anderen Einträgen. Bei Tausenden Einträgen werden diese internen Listen immer länger. Das verbraucht sehr viel Arbeitsspeicher. Die Leistung wird dadurch immer schlechter.
Das gleiche Problem gibt es beim QueryBuilder in TYPO3.
Auch er verliert massiv Leistung bei der Wiederverwendung in Schleifen.
Die Regel ist sehr klar: Diese Bausteine sind für einzelne Aufgaben gemacht.
Sie eignen sich überhaupt nicht für endlose Schleifen.
Das passt nicht zu ihrem Aufbau.
Messung der Leistung
Testumgebung mit gleichen Bedingungen
Gleiche Bedingungen sind sehr wichtig für einen echten Test. Unsere Testumgebung nutzt bekannte, freie Programme:
Aufbau:
- TYPO3 v12 LTS in einem DDEV-Behälter
- Symfony Commands für Befehle auf der Textoberfläche
- 10.000 Test-Einträge. Wir haben diese mit
fakerphp/fakererstellt. - Messungen: Wir messen die genaue Zeit und den höchsten Speicherverbrauch.
Erster Test: 10.000 Einträge
Der erste Test zeigt einen einfachen Import von vielen Daten. Wir laden alle 10.000 Einträge in eine einzige Liste. Wir übergeben diese Liste direkt an einen einzigen DataHandler.
| Metrik | Wert | Einheit |
|---|---|---|
| Dauer der Ausführung | 412.58 s | Sekunden |
| Höchster Speicherverbrauch | 784.31 MB | Megabyte |
| Verarbeitung | 24.24 rec/s | Einträge/Sekunde |
Ergebnis: Das Programm läuft fast 7 Minuten. Es verbraucht etwa 800 Megabyte Arbeitsspeicher. Es verarbeitet nur 24 Einträge pro Sekunde. Das ist für große Firmen viel zu langsam.
Vergleich der Leistung: Der Unterschied ist riesig. Die Leistung steigt von 24 auf 258 Einträge pro Sekunde.
Suche nach den Bremsen im System
Wir haben das Programm mit Xdebug genau untersucht. Es gibt nicht nur eine einzige große Bremse im Code. Es gibt viele kleine Bremsen. Das sind die größten Verbraucher:
- Leeren vom Cache: Das System leert dauernd den Zwischenspeicher.
- Referenzindex: Das System pflegt alle Verbindungen zwischen Daten. Das braucht viele Abfragen in der Datenbank.
- Protokoll und Verlauf: Das System schreibt viele Einträge in das Protokoll.
- Erweiterungen: Das System sucht nach weiteren Funktionen und ruft sie auf.
Wir müssen nicht jede kleine Rechnung im Code verbessern. Wir müssen ganze Gruppen von Aufgaben komplett überspringen.
Verteilung der Bremsen: Das Leeren vom Zwischenspeicher ist das größte Problem. Danach kommt der Referenzindex.
Verbesserung der Leistung: Einfache Anleitung
Einstellungen für den DataHandler im Code
Der DataHandler hat verschiedene Eigenschaften im Code. Sie wirken wie Schalter für bestimmte Funktionen. Wir können diese für große Datenmengen sehr sicher ausschalten:
// Protokoll ausschalten
$dataHandler->enableLogging = false;
// Prüfungen der Rechte umgehen (nur für Administratoren)
$dataHandler->bypassAccessCheckForRecords = true;
// Prüfung nach dem Speichern ausschalten
$dataHandler->checkStoredRecords = false;Sie haben das Leeren vom Zwischenspeicher für jeden Eintrag ausgeschaltet.
Sie müssen den Zwischenspeicher nach dem Import zwingend einmal komplett leeren: vendor/bin/typo3 cache:flush
Verbesserungen an TCA und Datenbank
Versionen ausschalten:
// Versionen für die Tabelle beim Import ausschalten
$GLOBALS['TCA']['tx_news_domain_model_news']['ctrl']['versioningWS'] = false;Index für die Datenbank:
Die Datenbank braucht einen guten Index für alle wichtigen Spalten.
Ein Index ist wie ein schnelles Inhaltsverzeichnis.
Wichtige Spalten sind zum Beispiel pid, deleted und hidden.
Fehlt dieses Verzeichnis, helfen auch keine anderen Verbesserungen.
Die wichtigste Strategie: Verarbeitung in Paketen
Die wichtigste Verbesserung ist die Verarbeitung in kleinen Paketen. Wir zeigen Ihnen unser Vorgehen:
// Verarbeitung in Paketen von 500 Einträgen
$chunks = array_chunk($records, 500);
foreach ($chunks as $chunk) {
// NEUER DataHandler für jedes Paket
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->enableLogging = false;
$dataHandler->bypassAccessCheckForRecords = true;
$dataMap = [];
foreach ($chunk as $record) {
$dataMap['tx_news_domain_model_news']['NEW' . uniqid()] = $record;
}
$dataHandler->start($dataMap, []);Die Verarbeitung in Paketen ist bei Fehlern manchmal unsicher.
Nutzen Sie für wichtige Daten sichere Transaktionen.
Eine Transaktion speichert Daten nur komplett oder gar nicht.
Dafür gibt es eine einfache Erweiterung.
Sie heißt wazum/transactional-data-handler.
Oder Sie steuern die Datenbank direkt über Doctrine DBAL.
Nutzen Sie dafür Befehle wie beginTransaction(), commit() und rollback().
Vergleich der Ergebnisse
Diese Tabelle zeigt die Wirkung von allen Verbesserungen zusammen:
| Konfiguration | Zeit (s) | Verbesserung | Speicher (MB) | Verbesserung |
|---|---|---|---|---|
| Grundwert (Eine Instanz) | 412.58 | 0.0% | 784.31 | 0.0% |
| Protokoll ist aus | 385.11 | 6.7% | 780.15 | 0.5% |
| + Rechteprüfung umgangen | 351.45 | 14.8% | 775.9 | 1.1% |
| + Versionen aus (TCA) | 298.62 | 27.6% | 768.55 | 2.0% |
| Paketverarbeitung (500 pro Paket) | 59.34 | 85.6% | 121.45 | 84.5% |
| Alle Verbesserungen zusammen | 38.77 | 90.6% | 98.5 | 87.4% |
Fazit: Einzelne kleine Änderungen bringen nur kleine Verbesserungen. Das sind etwa 6 bis 27 Prozent. Die Verarbeitung in Paketen bringt einen riesigen Gewinn von über 85 Prozent. Alle Strategien zusammen sparen ganze 90,6 Prozent Zeit. Sie verbrauchen 87,4 Prozent weniger Arbeitsspeicher.
Die Verarbeitung steigt von 24 Einträgen auf 257 Einträge pro Sekunde. Das ist ein riesiger Vorteil für große Firmen.
Bilder zur Leistung: Ausführungszeit
Die schrittweise Verbesserung zeigt klare Ergebnisse. Einzelne Änderungen bringen wenig. Aber die Verarbeitung in Paketen bringt ganze 85 Prozent weniger Zeit.
Bilder zur Leistung: Verbrauch von Speicher
Der Verbrauch von Arbeitsspeicher sinkt erst durch die Pakete sehr stark. Er fällt von 784 Megabyte auf unter 100 Megabyte.
Neuer Aufbau: Ein Plan für die Zukunft
Kritik am großen Aufbau
Der Hauptgrund für die schwache Leistung ist der große Aufbau. Das System verbindet das reine Speichern fest mit vielen anderen Regeln. Dazu gehören Rechte, Versionen, Protokolle und der Zwischenspeicher. Das sichert die Daten im normalen Betrieb sehr gut. Aber bei großen Datenmengen bremst es das System extrem aus.
Das Entwicklerteam von TYPO3 weiß das. Sie haben ein neues Projekt für diese Aufgabe gegründet. Das Projekt löst genau dieses Problem. Es trennt Aufgaben wie Prüfung, Rechte und Protokoll sauber auf. Daraus entstehen einzelne kleine Werkzeuge. Das Projekt ist seit Dezember 2024 fertig.
Grundregeln: Trennung von Aufgaben und kein gemerkter Zustand
Ein moderner Aufbau besteht aus Bausteinen:
- Dienst für das Speichern (
PersistenceService): Klein und ohne gemerkten Zustand. Er arbeitet nur für die Datenbank. - Dienst für Rechte (
PermissionService): Er prüft nur die Rechte der Benutzer. - Dienst für Prüfungen (
ValidationService): Er prüft die Regeln und Daten. - Dienst für Versionen (
VersioningService): Er baut die Versionen für Arbeitsbereiche. - Dienst für Protokolle (
LoggingService): Er schreibt den genauen Verlauf auf. - Dienst für den Zwischenspeicher (
CacheService): Er leert den Zwischenspeicher.
Aufbau ohne gemerkten Zustand: Die Dienste bekommen ihre Informationen direkt bei jedem Aufruf. Sie sammeln keine alten Daten an. Das ist sicher für lange Aufgaben und häufige Wiederholungen.
Entwurf für einen Dienst für viele Daten
Mit kleinen Bausteinen bauen wir sehr schnelle Lösungen:
// Nur benötigte Dienste laden
constructor(
private persistenceService: PersistenceService,
private cacheService: CacheService
) {}
async bulkImport(records: Record[]) {
// Transaktion von Hand steuern
await this.connection.beginTransaction()
try {
const chunks = chunkArray(records, 500)
for (const chunk of chunks) {
// Direktes Speichern ohne BallastFür normale Aufgaben im Hintergrund regelt das Hauptsystem alle Dienste. Für extrem schnelle Aufgaben bauen Entwickler eigene neue Lösungen. Sie nutzen dann nur die unbedingt notwendigen Dienste.
Zusammenfassung und Empfehlungen
Wichtigste Ergebnisse
- Aufbau für Sicherheit: Der DataHandler achtet auf absolute Sicherheit der Daten. Er achtet nicht auf höchste Geschwindigkeit. Das ist pure Absicht.
- Normale Leistung: 10.000 Einträge brauchen fast 7 Minuten. Sie brauchen etwa 800 Megabyte Speicher. Das reicht für große Datenmengen nicht aus.
- Gemerkter Zustand bremst: Das Ansammeln von Daten verbraucht den Arbeitsspeicher. Es macht das System sehr langsam.
- 90 Prozent mehr Leistung: Pakete und das Abschalten von Funktionen helfen enorm. Die Leistung steigt auf 257 Einträge pro Sekunde.
- Der Weg in die Zukunft: Das neue Projekt vom TYPO3-Team ist fertig. Es bietet bald kleine und getrennte Dienste an.
Empfehlungen für die Praxis
Pflicht zur Paketverarbeitung
Sehr wichtig: Nutzen Sie bei über 100 Einträgen immer Pakete zur Verarbeitung. Bauen Sie einen neuen DataHandler für jedes Paket. Ein Paket enthält etwa 250 bis 500 Einträge. Das bringt den größten Gewinn bei der Leistung.
Schalter für die Leistung
Große Wirkung: Schalten Sie auf der Befehlszeile das Protokoll aus. Schalten Sie auch die Prüfung für die Rechte aus. Schalten Sie die Prüfung nach dem Speichern aus. Schalten Sie die Versionen über das TCA komplett aus. Machen Sie das nur, wenn Sie diese nicht brauchen.
Sichere Transaktionen
Sichere Daten: Sichern Sie die Pakete mit einer Datenbank-Transaktion. Nutzen Sie dafür Befehle für Ihre Datenbank. Wenn ein Fehler passiert, macht das System keine halben Sachen.
Zwischenspeicher klug leeren
Hoher Nutzen: Leeren Sie den Zwischenspeicher nicht bei jedem Eintrag. Leeren Sie ihn nur einmal ganz am Ende. Das spart dem System sehr viel Kraft.
Ergebnisse vom TYPO3-Team
Sicher für die Zukunft: Das neue TYPO3-Projekt für Daten ist fertig. Nutzen Sie die neuen, getrennten Dienste. Diese gibt es in den neuen Versionen von TYPO3.
Die Datenbank als Basis
Grundlage: Ein sauberer Index für alle wichtigen Spalten ist Pflicht. Ein Index hilft der Datenbank beim Suchen. Ohne diesen Index bringen auch Änderungen im Code gar nichts.
Die DataHandler-Klasse: Aufbau und wichtige Eigenschaften
Die Klasse für den DataHandler hat viele Schalter im Code. Sie steuern sein Verhalten. Hier sind die wichtigsten Schalter für eine gute Leistung:
Wichtige Schalter für die Leistung
Anwendung: Beste Einstellungen für den Import
Versionen im TCA steuern
Komplette Funktion für einen schnellen Import
Sie finden den ganzen Code mit allen Befehlen am Ende dieses Textes. Er enthält auch die Behandlung von Fehlern und Fortschritts-Anzeigen. Sie können diese Befehle direkt in Ihre Projekte mit TYPO3 ab Version 12 übernehmen.