このページは機械翻訳されています。英語の原文をお読みください。 English

IBSurgeon ライブラリ

Firebirdデータベースを高速化する45の方法

ここでは、Firebirdデータベースのパフォーマンス向上のためのヒントを、ハードウェア/OSやFirebird設定のチューニングからSQL最適化の推奨事項まで、さまざまな分野にわたって紹介しています。このリストはFirebirdを最適化するための完全なリファレンスではなく、実行計画、トランザクション管理、クエリのパフォーマンス統計など、Firebirdの基本動作を理解していることを前提としています。

これらのヒントは慎重に適用し、本番環境に導入する前にその効果を検証してください。

当社(IBSurgeon)は、包括的なデータベースパフォーマンス最適化サービスを提供しています。

1. データベースをSSDに配置する

データベースをSSDに配置してください。SSDドライブは従来のドライブよりもはるかに優れたランダムIOを提供します。ランダムIOは、大きなデータベースファイル全体に分散したデータの読み書きに重要です。データベース操作の大半は、集中的な並列ランダムIOを必要とします。

2. RAID 10を使用する

RAID1またはRAID5を使用している場合は、RAID10を検討してください。15〜25%高速です。

3. BBUを確認する

RAIDコントローラを使用している場合は、バックアップバッテリユニット(BBU)がインストールされ、動作していることを確認してください。一部のベンダーはデフォルトでBBUを提供していません。BBUがない場合、コントローラはキャッシュを無効化し、RAIDは通常のSATAドライブよりも遅く動作します。通常、BBUのステータスはRAID設定ツールで確認できます。

4. ライトキャッシュをライトバックに設定する

BBUがインストールされたRAIDコントローラ(およびUPS付きサーバー)を使用している場合は、そのキャッシュがライトバック(ライトスルーではない)に設定されていることを確認してください。「ライトバック」により、コントローラのライトキャッシュが有効になります。

5. リードキャッシュを有効にする

RAIDコントローラを使用している場合は、リードキャッシュが有効になっていることを確認してください。

6. ディスクサブシステムを確認する

ドライブに不良ブロックやその他のハードウェア問題(過熱を含む)がないか確認してください。ハードウェアの問題はIOパフォーマンスを大幅に低下させ、データベースの破損につながる可能性があります。

7. Firebird 2.5でSuperClassicまたはClassicを使用する

Firebird 2.5 SuperServerを多数の接続で使用している場合は、SuperClassicまたはClassicの使用を試してください。これらはCPUの全コアを使用することで、より優れたスケーラビリティを発揮できます。

8. Firebird 3でSuperServer 3.0を使用する

2.5でClassicまたはSuperClassicを使用している場合は、Firebird 3.0 SuperServerへの移行を検討してください。現在では複数コアを使用でき、共有キャッシュの利点と組み合わせることができます。

9. ページバッファキャッシュを増やす

ページバッファキャッシュのサイズ(パラメータDefaultDBCachePages)をデフォルト値から増やしてください。2.5 SuperServerでは10000ページ、3.0 SuperServerでは50000ページ、ClassicおよびSuperClassicでは256〜2048ページを推奨します。ただし、ページバッファキャッシュの値を高く設定しすぎないでください。キャッシュ同期にはコストがかかり、この値を調整してデータベース全体をRAMに配置するという考え方は機能しません。最適化済みのFirebird設定ファイルはこちらを使用してください:/ja/optimized-firebird-configuration/

10. ソート操作用のメモリサイズを増やす

firebird.confのTempCacheLimitパラメータの値を増やしてください。これはソート用の一時領域のキャッシュサイズを指定します。デフォルト値は低すぎます(Classicでは8Mb、SuperServerでは64Mb)。Classicでは少なくとも64Mb、SuperServerおよびSuperClassicでは1Gbを使用してください。繰り返しますが、#9の最適化済み設定ファイルを使用してください。

11. Forced Writesをオフにする(注意して!)

大量の挿入または更新アクティビティがある場合(HQbird MonLoggerで確認できます。詳細はHQbirdユーザーガイドの60ページを参照)、およびハードウェア障害から保護するためにUPSとレプリケーションがインストールされている場合は、Forced Writes設定をOFFにすることを検討してください。書き込み操作の速度を最大3倍向上させることができます。

12. Classic/SuperClassicのハッシュスロット数を増やす

ClassicおよびSuperClassicのLockHashSlotsパラメータの値を、デフォルトの1009から大きな素数(たとえば30011)に増やしてください。内部ロックメカニズムのキューが減少します。

13. Super Server 2.5でCPUアフィニティを使用する

SuperServer 2.5を使用している場合は、CPUAffinityパラメータを使用中のデータベース数と等しい値に設定してください。2.5のSuperServerは、特定のデータベースのリクエストを処理するために異なるCPUコアを使用できます。

14. 一時領域に高速ドライブを使用する

firebird.confのTempDirectoryパラメータの最初の部分を高速ディスク(SSDまたはRAMドライブ)に設定してください。大規模なソートの時間が短縮されます。たとえば、データベースの復元時などです。

15. データベースバックアップを別のドライブに保存する

データベースバックアップを専用の物理ドライブ(RAID)に保存してください。これにより、バックアップ中の読み取りと書き込みのIOが分離され、バックアップ速度が向上し、メインドライブの負荷が軽減されます。これは、ユーザーがデータベースを操作している間にバックアップを取る場合に特に重要です。Firebirdのハードウェア設定の詳細については、「Firebirdハードウェアガイド」を参照してください。

16. 一括挿入時にインデックスを無効化する

多数のレコード(テーブルの25%以上)を挿入または更新する場合は、レコードが挿入されるテーブルのインデックスを無効化し、挿入または更新後に再アクティブ化してください。インデックスの再構築操作は、インデックスの多数の更新よりも高速な場合があります。

17. 高速挿入にグローバル一時テーブルを使用する

挿入と更新を高速化するには、大規模なレコードセットの一括挿入にグローバル一時テーブル(GTT)を使用し、その後レコードを永続テーブルに転送します。GTTにレコードを挿入し、前処理を行ってから永続テーブルに移動する方法は非常に効果的です。

18. 不要なインデックスを避ける

挿入と更新が頻繁なテーブルでは、インデックスの数を減らしてください。各インデックスは、挿入、更新、削除、およびガベージコレクション操作に大きなオーバーヘッドを追加します。単一のレコードが挿入/更新/削除/クリーンアップされる際に、各インデックスに対して3〜4回の追加ページ読み取りと書き込みが発生する可能性があります。

19. UDFを組み込み関数呼び出しに置き換える

UDF呼び出しを組み込み関数呼び出しに置き換えてください。最近のFirebirdバージョンでは、以前はUDFライブラリでのみ利用可能だった機能を提供する多くの組み込み関数が追加されました。可能な場合はそのような関数を置き換えてください。組み込み関数はUDFよりも最大3倍高速に動作します。

20. 読み取り操作に読み取り専用トランザクションを使用する

レコードを変更しない操作(つまりSELECT)には、分離モードをread committedに設定した読み取り専用トランザクションを使用してください。このようなトランザクションはガベージコレクションからレコードバージョンを保持せず、無期限に実行できます。データベースのパフォーマンスに影響を与えません。

21. 短い書き込みトランザクションを使用し、すべての長時間実行トランザクションを排除する

短い書き込み可能トランザクション(INSERT/UPDATE/DELETE操作用)を使用してください。

書き込み可能トランザクションは短いほど良いです。短いトランザクションは、長時間実行トランザクションよりもガベージコレクションから保持するレコードバージョンの数が比例して少なくなります。残念ながら、単一の長時間実行トランザクション(たとえば開発ツールから開いたままになっているもの)でも、他のすべての短い書き込みトランザクションの良い効果を台無しにする可能性があります。そのため、長時間実行トランザクションを監視し、ソースコード内の適切な場所を修正する必要があります。HQbird DataGuardツールを使用して、Firebirdデータベース内の最も古いアクティブトランザクションに関するアラート(どのアプリケーションが開始したか、どのIPアドレスか、開始タイムスタンプ)を受け取り、HQbird MonLoggerツールを使用して長時間実行中のアクティブトランザクションの完全なリストとそのIO統計を確認してください。また、レコードセットをキャッシュできるデータベースアクセスコンポーネント/ライブラリを使用している場合は、キャッシュ更新を使用してください。

22. 長いレコードチェーンを避ける

1つのレコードに多数のレコードバージョンがある状況を避けてください。Firebirdは長いレコードチェーンでははるかに遅く動作します。(一部のテーブルにいくつのレコードバージョンがあるか、最長のレコードチェーンが何かを確認するには、HQbird IBAnalystツールのTablesタブで「Max Version」で並べ替えて確認できます。)同じレコードの複数回の更新ではなく、挿入と古いレコードの定期的な削除の組み合わせを使用してください。

23. 正确使用 PREPARE

使用预准备语句来执行仅参数发生变化的 SQL 查询–例如,在循环执行此类查询之前先进行预准备。预准备操作可能非常耗时(尤其是对于大表),而仅预准备一次查询将大幅提升整体性能。

24. 批量插入/更新操作时不要过于频繁地 COMMIT

在进行批量 INSERT/UPDATE/DELETE 操作时,不要在每个更改后都提交事务(如果数据库驱动中启用了自动提交选项,就可能发生这种情况)–至少每 1000 次操作或更多次操作后再提交事务。每次事务提交都会对数据库执行多次读写 IO 操作,因此频繁提交会降低数据库性能。

25. 使用包含大量常量的 IN 时“关闭”索引

如果使用 WHERE fieldX IN (Constant1, Constant2,… ConstantN) 这样的结构,并且 fieldX 上有索引,Firebird 会按照 IN 列表中常量的数量多次使用索引。通过将 fieldX 转换为表达式 +0 来禁用索引搜索:WHERE fieldX+0 IN (Constant1, Constant2,… ConstantN),或者对于字符串,使用 fieldX||''

26. 用 JOIN 替代 IN

避免使用嵌套的 WHERE IN(SELECT... WHERE IN (SELECT.. WHERE IN() )) 查询,这可能会让 Firebird 优化器感到困惑。将嵌套的 IN 转换为 JOIN。

27. 正确使用 LEFT JOIN

如果使用 LEFT OUTER JOIN,请明确地将表按从小到大的顺序放入连接中。

28. 限制 SELECT 查询的获取量

始终尝试使用 FIRST… SKIP 或 ROWS 子句来限制 SELECT 查询的大量输出。如果查询不是专门设计为报表(需要打印/导出所有记录),通常显示前 10-100 条记录就足够了。只获取必要的记录。

29. 在带 ORDER BY/GROUP BY 的 SELECT 中指定更少的列

在带 ORDER BY/GROUP BY 的查询中,减少 SELECT 部分(即要显示的字段)和 ORDER BY 子句中的列数及其总宽度。Firebird 会合并 SELECT 和 ORDER BY/GROUP BY 子句中的列,并在内存中排序(如果内存不足,则在磁盘上排序)。因此,如果 SELECT 中有长 VARCHAR,排序文件的大小可能非常大(数 GB)。仅减少必须排序的字段数量,并在后期连接大字段以显示,可以大幅(3-10 倍)提升带 ORDER BY/GROUP BY 的查询速度。

30. 使用派生表优化带 ORDER BY/GROUP BY 的 SELECT

另一种优化带排序的 SQL 查询的方法是使用派生表来避免不必要的排序操作。不要使用:

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

而使用以下修改版本:

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. 短字符串存 VARCHAR,长文本存 BLOB

存储短字符数据时使用 VARCHAR,存储长文本时使用 BLOB。VARCHAR 对于小块数据更快,因为它们存储在记录中,整个记录在同一个 IO 周期内被读取,如果记录大小小于数据库页面大小的 2/3,整个记录存储在同一数据库页面上。BLOB 存储在记录之外,需要额外的 IO 周期来读取,但在读写长字符串时它们显示出优势。

32. 从大型 SELECT 中排除 BLOB 列

从大型 SELECT 中排除 BLOB 列。使用带有子查询的后期绑定方式来有选择地显示 BLOB 中的信息(例如,显示文档的内容)。

33. 使用 BIGINT 作为主键和唯一键

使用 BIGINT 类型作为自增主键、唯一键以及所有类型的标识符。BIGINT 的操作速度最快,并且 BIGINT 有足够的容量来存储几乎所有数据范围。

34. 不要使用 VARCHAR 作为键

除非确实必要,否则不要使用 VARCHAR 作为标识符–对它们的操作远不如整数列高效。尤其要避免使用 GUID 作为标识符–由于 GUID 值的随机分布,使用 GUID 作为主键/唯一键的 INSERT/UPDATE 操作可能比使用整数慢 20 倍。

35. 重新计算索引统计信息

定期重新计算索引统计信息。使用 SET STATISTICS 命令更新频繁或大量更改的表的索引统计信息,这能让 Firebird 优化器选择更好的 SQL 计划。HQbird Firebird DataGuard 可以按照所需的计划(通常每周一次)自动执行此类索引统计信息的重新计算。

36. 使用连接池

如果到 Firebird 数据库的连接是短连接(这在网站中很典型),请使用连接池–例如,在 PHP 中使用 ibase_pconnect 函数而不是 ibase_connect

37. 在 Firebird 3.0 中使用 LINGER 选项

如果数据库连接是短连接且使用 Firebird 3+,请使用 LINGER 选项在指定时间内保持缓存活动,这样即使没有其他连接,也将在缓存中保留常用页面。例如,ALTER DATABASE SET LINGER TO 60 将在最后一个连接结束后保持缓存 60 秒。

38. 使用 HASH JOIN

在 Firebird 3.0 中,当连接大表和小表时,HASH JOIN 可能比使用索引的“嵌套循环”普通连接快得多。要让 Firebird 优化器使用 HASH JOIN,请在连接条件中使用 +0:T1 JOIN T2 ON T1.FIELD1+0 = T2.FIELD2+0。在投入生产环境之前,请检查优化结果!

39. 将适当的 PSQL 函数标记为 DETERMINISTIC

将没有参数且返回常量值的 PSQL 函数(Firebird 3+)标记为关键字 DETERMINISTIC。确定性函数会在当前查询的范围内被计算并缓存。

40. 在 Firebird 3.0 中使用分析(窗口)函数

如果运行的 SELECT 同时输出某个列及其聚合函数,请使用窗口(分析)函数–这比子查询或两个查询更快。例如:

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

替换为:

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

41. 为 gbak 使用 -se 开关

使用 -se 开关可将 gbak 备份和/或恢复速度提升最多 20%,例如:

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

42. WHERE CURRENT OF

在 PSQL 中处理游标获取的记录最快的方式是使用 where current of <> 子句。它比 where rb$db_key = :v_db_key 更快,并且比使用主键或唯一键搜索快得多。

43. 避免频繁查询监控表

不要过于频繁地运行对 Firebird 监控表(MON$)的查询–此类查询会消耗大量资源,并可能大幅降低主要业务逻辑的性能。我们建议 MON$ 查询的运行频率不超过每分钟一次。如需持续监控 Firebird 的查询/事务/连接,请使用支持 Trace API 的 HQbird PerfMon 工具(详情请参见 HQbird 用户指南 第 66 页)。

44. 批量插入/更新时使用 NO_AUTO_UNDO 选项

如果在同一事务框架内运行大量 DML(Update/Insert/Delete)命令,Firebird 会将每个命令的撤销日志与事务的撤销日志合并。为了加速批量 DML 操作,请使用「NO AUTO UNDO」选项启动事务,以避免将每个命令的撤销日志与事务的撤销日志合并。

45. 在 Firebird 3 中,如果不需要,请勿使用 SRP 认证

如果并非真正需要,请不要使用 SRP 用户认证(Firebird 3.0+)–使用 SRP 认证建立连接比常规连接更慢。

まとめの代わりに

パフォーマンス最適化には複数の要素を考慮する必要があり、非常に難しい場合があります。上記のすべてを試した場合は、プロフェッショナルなdatabase performance optimizationサービスを依頼することを検討してください。

お問い合わせ

ご質問がありますか?お気軽にメールでお問い合わせください。