Diese Seite wurde maschinell übersetzt. Lesen Sie das englische Original. English

IBSurgeon-Bibliothek

45 Möglichkeiten, um Firebird-Datenbanken zu beschleunigen

Hier finden Sie eine Liste mit Performance-Tipps für Firebird-Datenbanken in verschiedenen Bereichen - von Hardware/OS und Firebird-Konfigurationstuning bis hin zu SQL-Optimierungsempfehlungen. Diese Liste ist keine vollständige Referenz zur Optimierung von Firebird und setzt voraus, dass Sie die Grundlagen der Firebird-Funktionsweise verstehen, wie z. B. Ausführungspläne, Transaktionsverwaltung und Leistungsstatistiken für Abfragen.

Bitte wenden Sie diese Tipps mit Vorsicht an und verifizieren Sie ihre Wirkung, bevor Sie sie in der Produktion einsetzen.

Unser Unternehmen (IBSurgeon) bietet den umfassenden Service zur Datenbank-Performance-Optimierung an.

1. Datenbank auf SSD legen

Legen Sie Ihre Datenbank auf eine SSD. SSD-Laufwerke bieten einen deutlich besseren wahlfreien Zugriff (Random IO) als herkömmliche Laufwerke. Random IO ist entscheidend für das Lesen und Schreiben von Daten, die über eine große Datenbankdatei verteilt sind - die Mehrheit der Datenbankoperationen erfordert intensiven parallelen Random IO.

2. RAID 10 verwenden

Wenn Sie RAID1 oder RAID5 verwenden, ziehen Sie RAID10 in Betracht - es ist 15-25 % schneller.

3. BBU prüfen

Wenn Sie einen RAID-Controller verwenden, stellen Sie sicher, dass eine Backup Battery Unit (BBU) installiert und betriebsbereit ist - einige Hersteller liefern BBU nicht standardmäßig mit. Ohne BBU deaktiviert der Controller den Cache, und RAID arbeitet sehr langsam, sogar langsamer als normale SATA-Laufwerke. Normalerweise können Sie den BBU-Status im RAID-Konfigurationstool überprüfen.

4. Write-Cache auf Write-Back setzen

Wenn Sie einen RAID-Controller mit installierter BBU (und Server mit USV) verwenden, stellen Sie sicher, dass dessen Cache auf Write-Back (nicht Write-Through) eingestellt ist. „Write-Back“ aktiviert den Write-Cache des Controllers.

5. Read-Cache aktivieren

Wenn Sie einen RAID-Controller verwenden, stellen Sie sicher, dass der Read-Cache aktiviert ist.

6. Festplatten-Subsystem prüfen

Überprüfen Sie Ihre Laufwerke auf defekte Blöcke und andere Hardwareprobleme (einschließlich Überhitzung). Hardwareprobleme können die IO-Leistung erheblich verringern und zu Datenbankkorruptionen führen.

7. SuperClassic oder Classic in Firebird 2.5 verwenden

Wenn Sie Firebird 2.5 SuperServer mit vielen Verbindungen verwenden, versuchen Sie SuperClassic oder Classic - diese können durch die Nutzung aller CPU-Kerne besser skalieren.

8. SuperServer 3.0 in Firebird 3 verwenden

Wenn Sie Classic oder SuperClassic in 2.5 verwenden, ziehen Sie eine Migration auf Firebird 3.0 SuperServer in Betracht - dieser kann jetzt mehrere Kerne nutzen und dies mit den Vorteilen des gemeinsamen Caches kombinieren.

9. Seitenpuffer-Cache vergrößern

Vergrößern Sie die Größe des Seitenpuffer-Caches (Parameter DefaultDBCachePages) gegenüber den Standardwerten. Für 2.5 SuperServer empfehlen wir 10000 Seiten, für 3.0 SuperServer - 50000 Seiten, für Classic und SuperClassic - von 256 bis 2048 Seiten. Setzen Sie den Wert für den Seitenpuffer-Cache jedoch nicht zu hoch - die Cache-Synchronisierung hat ihren Preis, und die Idee, die gesamte Datenbank durch die Anpassung dieses Werts in den RAM zu legen, wird nicht funktionieren. Verwenden Sie hier voroptimierte Firebird-Konfigurationsdateien: /de/optimized-firebird-configuration/

10. Speichergröße für Sortieroperationen erhöhen

Erhöhen Sie den Wert des Parameters TempCacheLimit in firebird.conf - er legt die Größe des Caches des temporären Speicherplatzes für das Sortieren fest. Die Standardwerte sind zu niedrig (8 MB für Classic und 64 MB für SuperServer); verwenden Sie mindestens 64 MB für Classic und 1 GB für SuperServer und SuperClassic. Verwenden Sie auch hier die optimierten Konfigurationsdateien aus #9.

11. Forced Writes ausschalten (mit Vorsicht!)

Wenn Sie intensive Einfüge- oder Aktualisierungsaktivitäten haben (Sie können dies mit HQbird MonLogger überprüfen, Details finden Sie auf Seite 60 des HQbird-Benutzerhandbuchs), und wenn Sie USV und Replikation installiert haben, um vor Hardwareausfällen zu schützen, ziehen Sie in Betracht, die Forced Writes-Einstellung auf OFF zu setzen - dies kann die Geschwindigkeit von Schreiboperationen um bis zu 3 Mal erhöhen.

12. Anzahl der Hash-Slots für Classic/SuperClassic erhöhen

Erhöhen Sie den Wert des Parameters LockHashSlots für Classic und SuperClassic vom Standardwert 1009 auf eine große Primzahl (z. B. 30011) - dies verringert Warteschlangen im internen Sperrmechanismus.

13. CPU-Affinität für SuperServer 2.5 verwenden

Wenn Sie SuperServer 2.5 verwenden, setzen Sie den Parameter CPUAffinity auf einen Wert, der der Anzahl der verwendeten Datenbanken entspricht: SuperServer in 2.5 kann verschiedene CPU-Kerne verwenden, um Anfragen für bestimmte Datenbanken zu verarbeiten.

14. Schnelles Laufwerk für temporären Speicherplatz verwenden

Setzen Sie den ersten Teil des Parameters TempDirectory in firebird.conf auf ein schnelles Laufwerk - SSD oder RAM-Disk. Dies verringert die Zeit großer Sortiervorgänge - z. B. wenn die Datenbank wiederhergestellt wird.

15. Datenbanksicherungen auf einem anderen Laufwerk speichern

Speichern Sie Datenbanksicherungen auf einem dedizierten physischen Laufwerk (RAID). Dies trennt Lese- und Schreib-IO während der Sicherung, erhöht die Sicherungsgeschwindigkeit und verringert die Last auf dem Hauptlaufwerk. Dies ist besonders wichtig, wenn Sicherungen erstellt werden, während Benutzer mit der Datenbank arbeiten. Weitere Details zur Hardwarekonfiguration für Firebird finden Sie im „Firebird Hardware Guide“.

16. Indizes für Masseneinfügungen deaktivieren

Wenn Sie viele Datensätze einfügen oder aktualisieren (mehr als 25 % der Tabelle), deaktivieren Sie die Indizes für die Tabelle, in die Datensätze eingefügt werden, und reaktivieren Sie sie nach dem Einfügen oder Aktualisieren. Der Neuaufbau des Index kann schneller sein als viele Aktualisierungen des Index.

17. Globale temporäre Tabellen für schnelle Einfügungen verwenden

Um Einfügungen und Aktualisierungen zu beschleunigen, verwenden Sie Globale temporäre Tabellen für Masseneinfügungen großer Recordsets und übertragen Sie die Datensätze dann in die permanente Tabelle. Es kann sehr effektiv sein, Datensätze in GTT einzufügen, sie vorzuverarbeiten und dann in die persistente Tabelle zu verschieben.

18. Unnötige Indizes vermeiden

Verwenden Sie weniger Indizes für Tabellen mit intensiven Einfügungen und Aktualisierungen. Jeder Index fügt erheblichen Overhead für Einfüge-, Aktualisierungs-, Lösch- und Garbage-Collection-Operationen hinzu - es können 3-4 zusätzliche Seitenlese- und -schreibvorgänge auftreten, wenn ein einzelner Datensatz für jeden Index eingefügt/aktualisiert/gelöscht/bereinigt wird.

19. UDFs durch eingebettete Funktionsaufrufe ersetzen

Ersetzen Sie UDF-Aufrufe durch eingebettete Funktionsaufrufe. In den neueren Versionen von Firebird wurden viele eingebettete Funktionen hinzugefügt, die Funktionalität bieten, die zuvor nur in UDF-Bibliotheken verfügbar war. Ersetzen Sie solche Funktionen, wo möglich, da eingebettete Funktionen bis zu 3 Mal schneller arbeiten als UDFs.

20. Read-only-Transaktionen für Leseoperationen verwenden

Verwenden Sie Read-only-Transaktionen für Operationen, die keine Datensätze ändern (d. h. SELECTs) mit dem Isolationsmodus Read Committed. Solche Transaktionen behalten keine Datensatzversionen aus der Garbage Collection zurück und können unbegrenzt laufen: Sie beeinträchtigen die Datenbankleistung nicht.

21. Kurze Schreibtransaktionen verwenden und ALLE langlaufenden Transaktionen beseitigen

Verwenden Sie kurze beschreibbare Transaktionen (für Operationen INSERT/UPDATE/DELETE).

Je kürzer die beschreibbare Transaktion ist, desto besser. Kurze Transaktionen behalten proportional weniger Datensatzversionen aus der Garbage Collection zurück als langlaufende. Leider kann bereits eine einzige langlaufende Transaktion (z. B. aus einem offen gelassenen Entwicklungstool) den guten Effekt aller anderen kurzen beschreibbaren Transaktionen zunichtemachen. Deshalb müssen Sie langlaufende Transaktionen überwachen und die entsprechenden Stellen im Quellcode korrigieren. Verwenden Sie das HQbird DataGuard-Tool, um Warnungen über die älteste aktive Transaktion in der Firebird-Datenbank zu erhalten (welche Anwendungen sie gestartet haben, welche IP-Adresse, der Zeitstempel ihres Starts), und das HQbird MonLogger-Tool, um die vollständige Liste der langlaufenden aktiven Transaktionen und ihre IO-Statistiken zu sehen. Wenn Sie außerdem Datenbankzugriffskomponenten/-bibliotheken verwenden, die Recordsets cachen können, verwenden Sie Cached Updates.

22. Lange Datensatzketten vermeiden

Vermeiden Sie Situationen, in denen ein Datensatz viele Datensatzversionen hat - Firebird arbeitet mit langen Datensatzketten viel langsamer. (Um zu sehen, wie viele Datensatzversionen einige Tabellen haben und wie lang die längste Datensatzkette ist, können Sie das HQbird IBAnalyst-Tool verwenden, Registerkarte Tabellen, Sortierung nach „Max Version“). Verwenden Sie eine Kombination aus Einfügungen und geplantem Löschen alter Datensätze anstelle mehrerer Aktualisierungen desselben Datensatzes.

23. PREPARE korrekt verwenden

Verwenden Sie vorbereitete Anweisungen (Prepared Statements), um SQL-Abfragen auszuführen, bei denen nur Parameter geändert werden - z. B. Prepare vor der Schleife solcher Abfragen. Prepare kann erhebliche Zeit in Anspruch nehmen (insbesondere bei großen Tabellen), und das nur einmalige Vorbereiten der Abfrage wird die Gesamtleistung erheblich erhöhen.

24. Nicht zu oft COMMIT während Masseneinfüge-/Aktualisierungsoperationen

Führen Sie bei Massen-INSERT/UPDATE/DELETE-Operationen nicht nach jeder Änderung einen Commit der Transaktion durch (dies kann passieren, wenn Sie die Auto-Commit-Option in Ihrem Datenbanktreiber verwenden) - committen Sie die Transaktion mindestens nach 1000 Operationen oder mehr. Jeder Transaktions-Commit führt mehrere Lese-/Schreib-IO-Operationen gegen die Datenbank aus, daher verringern häufige Commits die Datenbankleistung.

25. Indizes „ausschalten“, wenn Sie IN mit vielen Konstanten verwenden

Wenn Sie die Konstruktion WHERE fieldX IN (Constant1, Constant2,… ConstantN) verwenden und ein Index auf fieldX existiert, wird Firebird den Index so oft verwenden, wie Konstanten in der IN-Liste sind. Deaktivieren Sie die Indexsuche, indem Sie fieldX in einen Ausdruck +0 umwandeln: WHERE fieldX+0 IN (Constant1, Constant2,… ConstantN), oder verwenden Sie für Strings fieldX||''

26. IN durch JOIN ersetzen

Vermeiden Sie Abfragen mit verschachteltem WHERE IN(SELECT… WHERE IN (SELECT.. WHERE IN() )), da dies den Firebird-Optimierer verwirren kann. Transformieren Sie verschachtelte INs in Joins.

27. LEFT JOIN korrekt verwenden

Wenn Sie LEFT OUTER Joins verwenden, setzen Sie die Tabellen im Join explizit von der kleinsten zur größten.

28. Fetch von SELECT-Abfragen begrenzen

Versuchen Sie immer, die große Ausgabe von SELECT-Abfragen mit FIRST… SKIP- oder ROWS-Klauseln zu begrenzen. Wenn die Abfrage nicht speziell als Bericht konzipiert ist (der alle Datensätze zum Drucken/Exportieren erfordert), reicht es normalerweise aus, die Top 10-100 Datensätze anzuzeigen. Fetchen Sie nur die notwendigen Datensätze.

29. Weniger Spalten in SELECT mit ORDER BY/GROUP BY angeben

Reduzieren Sie die Anzahl der Spalten und ihre Gesamtbreite in Abfragen mit ORDER BY/GROUP BY sowohl im SELECT-Teil (d. h. die anzuzeigenden Felder) als auch in der ORDER BY-Klausel. Firebird führt Spalten aus SELECT und ORDER BY/GROUP BY-Klauseln zusammen und sortiert sie im Speicher (oder, wenn der Speicher nicht ausreicht, auf der Festplatte). Wenn also ein langes VARCHAR im SELECT steht, kann die Größe der Sortierdateien wirklich groß sein (viele Gigabyte). Die Reduzierung der Felder nur auf diejenigen, die sortiert werden müssen, und ein späterer Join mit den großen anzuzeigenden Feldern kann die Geschwindigkeit einer Abfrage mit ORDER BY/GROUP BY erheblich (x3-x10) erhöhen.

30. Abgeleitete Tabellen zur Optimierung von SELECT mit ORDER BY/GROUP BY verwenden

Eine weitere Möglichkeit, SQL-Abfragen mit Sortierung zu optimieren, ist die Verwendung abgeleiteter Tabellen, um unnötige Sortieroperationen zu vermeiden. Statt

Code
SELECT FIELD_KEY, FIELD1, FIELD2, ... FIELD_NFROM TORDER BY FIELD2

verwenden Sie die folgende Modifikation:

Code
SELECT T.FIELD_KEY, T.FIELD1, T.FIELD2, ... T.FIELD_NFROM (SELECT FIELD_KEY FROM T ORDER BY FIELD2) T2JOIN T ON T.FIELD_KEY = T2.FIELD_KEY

31. Kurze Strings in VARCHAR, lange in BLOBs speichern

Verwenden Sie für kurze Zeichendaten VARCHARs und für lange Texte BLOBs. Varchars sind für kleine Datenmengen schneller, da sie im Datensatz gespeichert werden und der gesamte Datensatz im selben IO-Zyklus gelesen wird; wenn die Datensatzgröße weniger als 2/3 der Datenbankseitengröße beträgt, wird der gesamte Datensatz auf derselben Datenbankseite gespeichert. BLOBs werden außerhalb des Datensatzes gespeichert und erfordern eine zusätzliche IO-Runde zum Lesen; sie zeigen ihren Vorteil beim Lesen und Schreiben langer Strings.

32. BLOB-Spalten aus großen SELECTs ausschließen

Schließen Sie BLOB-Spalten aus großen SELECTs aus. Verwenden Sie eine Art späte Bindung mit Unterabfragen, um Informationen aus BLOBs selektiv anzuzeigen (z. B. den Inhalt des Dokuments anzeigen).

33. BIGINT für Primär- und Unique-Schlüssel verwenden

Verwenden Sie den Typ BIGINT für automatisch inkrementierte Primär- und Unique-Schlüssel und für Identifikatoren aller Art. Operationen mit BIGINT sind am schnellsten, und BIGINT hat genügend Kapazität, um fast alle Datenbereiche zu speichern.

34. Verwenden Sie keine VARCHARs für Schlüssel

Verwenden Sie VARCHAR nicht für Identifikatoren, es sei denn, es ist wirklich notwendig - Operationen damit sind weitaus weniger effizient als mit Integer-Spalten. Vermeiden Sie insbesondere GUIDs als Identifikatoren - aufgrund der zufälligen Verteilung von GUID-Werten können INSERT/UPDATE-Operationen mit Primary/Unique Keys auf GUIDs bis zu 20-mal langsamer sein als mit Integern.

35. Indizes-Statistiken neu berechnen

Berechnen Sie Indizes-Statistiken regelmäßig neu. Aktualisieren Sie die Indizes-Statistiken für Tabellen mit häufigen oder massiven Änderungen mit dem Befehl SET STATISTICS. Dies ermöglicht dem Firebird-Optimierer, bessere SQL-Pläne zu wählen. HQbird Firebird DataGuard kann eine solche Neuberechnung der Indizes-Statistiken automatisch nach dem gewünschten Zeitplan durchführen (normalerweise einmal pro Woche).

36. Verbindungspool verwenden

Wenn Datenbankverbindungen zur Firebird-Datenbank kurzlebig sind (typisch für Websites), verwenden Sie einen Verbindungspool - zum Beispiel in PHP die Funktion ibase_pconnect anstelle von ibase_connect.

37. LINGER-Option in Firebird 3.0 verwenden

Wenn Datenbankverbindungen kurzlebig sind und Sie Firebird 3+ verwenden, nutzen Sie die LINGER-Option, um den Cache für eine bestimmte Zeit aktiv zu halten. So bleiben häufig verwendete Seiten im Cache, auch wenn keine anderen Verbindungen bestehen. Zum Beispiel hält ALTER DATABASE SET LINGER TO 60 den Cache 60 Sekunden nach dem Ende der letzten Verbindung aufrecht.

38. HASH JOINs verwenden

In Firebird 3.0 kann beim Verbinden großer und kleiner Tabellen ein HASH JOIN viel schneller sein als ein normaler Join, der eine „Nested Loop" mit Index verwendet. Um den Firebird-Optimierer zur Verwendung von HASH JOIN zu bewegen, verwenden Sie +0 in der Join-Bedingung: T1 JOIN T2 ON T1.FIELD1+0 = T2.FIELD2+0. Überprüfen Sie das Ergebnis der Optimierung, bevor Sie es in die Produktion übernehmen!

39. Geeignete PSQL-Funktionen als DETERMINISTIC markieren

Markieren Sie Ihre PSQL-Funktionen (in Firebird 3+), die keine Parameter haben und konstante Werte zurückgeben, mit dem Schlüsselwort DETERMINISTIC. Die deterministischen Funktionen werden im Rahmen der aktuellen Abfrage berechnet und zwischengespeichert.

40. Analytische (Fenster-)Funktionen in Firebird 3.0 verwenden

Wenn Sie eine SELECT-Abfrage mit gleichzeitiger Ausgabe einer Spalte und einer Aggregatfunktion dafür ausführen, verwenden Sie Fenster- (analytische) Funktionen - das ist schneller als eine Unterabfrage oder zwei Abfragen. Zum Beispiel:

Code
Select id, department, salary, salary / (select sum(salary) from employee) percentagefrom employee

ersetzen durch:

Code
Select id, department, salary, salary / sum(salary) OVER () percentage from employee

41. Schalter -se für gbak verwenden

Verwenden Sie den Schalter -se, um die Geschwindigkeit von gbak-Backup und/oder -Restore um bis zu 20% zu erhöhen, zum Beispiel:

Code
gbak -b -g -se service_mgr c:\db\data.fdb e:\backup\data.fbk

42. WHERE CURRENT OF

Der schnellste Weg, um vom Cursor in PSQL abgerufene Datensätze zu verarbeiten, ist die Klausel „where current of <>". Sie ist schneller als „where rb$db_key = :v_db_key" und viel schneller als eine Suche mit einem Primär- oder Unique-Key.

43. Häufige Abfragen auf Monitoring-Tabellen vermeiden

Führen Sie Abfragen auf Firebird-Monitoring-Tabellen (MON$) nicht zu oft aus - solche Abfragen verbrauchen erhebliche Ressourcen und können die Leistung der Hauptgeschäftslogik stark beeinträchtigen. Wir empfehlen, MON$-Abfragen nicht häufiger als einmal pro Minute auszuführen. Für kontinuierliches Monitoring von Firebird-Abfragen/Transaktionen/Attachments verwenden Sie das HQbird PerfMon-Tool, das die Trace-API unterstützt (siehe Seite 66 des HQbird-Benutzerhandbuchs für Details).

44. NO_AUTO_UNDO-Option für Bulk-Inserts/Updates verwenden

Wenn Sie viele DML-Befehle (Update/Insert/Delete) im Rahmen derselben Transaktion ausführen, führt Firebird das Undo-Log jedes Befehls mit dem Undo-Log der Transaktion zusammen. Um Bulk-DML-Operationen zu beschleunigen, starten Sie die Transaktion mit der Option „NO AUTO UNDO", um die Undo-Logs der einzelnen Befehle nicht mit dem Undo-Log der Transaktion zusammenzuführen.

45. SRP-Authentifizierung in Firebird 3 nicht verwenden, wenn Sie sie nicht benötigen

Verwenden Sie keine SRP-Benutzerauthentifizierung (Firebird 3.0+), wenn Sie sie nicht wirklich benötigen - die Verbindung mit SRP-Authentifizierung wird langsamer aufgebaut als eine reguläre Verbindung.

Statt einer Zusammenfassung

Die Leistungsoptimierung erfordert die Berücksichtigung mehrerer Faktoren und kann wirklich knifflig sein. Wenn Sie alle oben genannten Punkte ausprobiert haben, ziehen Sie in Betracht, einen professionellen Datenbank-Leistungsoptimierungsdienst zu beauftragen.

Kontaktieren Sie uns

Haben Sie Fragen? Zögern Sie nicht, uns per E-Mail zu kontaktieren!