1 TBのFirebirdデータベース:予備レポート
Dmitry Kuzmenko、最終更新日:2014年3月31日
さらに大きな(1.7テラバイト)データベースに関する記事もお読みください:1.7テラバイトデータベースの詳細。
なぜテラバイト規模のFirebirdデータベースを作成するのか?
多くの企業が大規模なFirebirdデータベースを運用し、重要な業務を支えるためにそれらに依存しています。Firebirdデータベースの中には、すでに数百ギガバイトのサイズに達し、成長を続けているものもあります(「大規模データベースの事例」セクションを参照)。そして、それらが2倍、3倍、5倍に大きくなる瞬間を予測するのは簡単です。そのため、データベース管理者やベンダーは、大規模データベースでのFirebirdの動作を調査し、それらを管理するための推奨事項を得ることに興味を持っています。
また、1TbのFirebirdデータベースを作成する際に私たちが念頭に置いていた重要な理由は、Firebirdを「小規模データベース用」のデータベースエンジンとする一般的な認識を最終的に払拭することでした。この神話は今や消え去ったように見えますが、一部のアナリストやジャーナリストは定期的にそれを掘り起こします。私たちはこの馬鹿げた認識にようやく終止符を打つことを望んでいます。
| ## ハードウェア |
Firebirdはその驚異的なスケーラビリティでよく知られており、この調査はそれを再び確認しました。この実験の当初の目的は、単に1TbサイズのFirebirdデータベースを作成することだったため、通常のデスクトップコンピュータを使用しました:
表1:ハードウェア
| コンポーネント | パラメータ |
| CPU | AMDAthlon 64 x2 5200 |
| RAM | 4GB |
| マザーボード | MSI K9N Platinum |
| HDD1(オペレーティングシステムと一時ファイル) | ST3160815AS、160GB、SATA II |
| HDD2(補助) | HDT721064SLA360、640GB、SATAII |
| HDD2(補助) | HDS728080PLA380、80GB、SATA I |
| HDD3(データベース) | ST31500341AS、1.5TB、SATA II(ファームウェアCC1H) |
基本的に、私たちはオフィスのデスクトップの1台に1.5TbのHDDを追加しただけで、他の変更は一切行いませんでした。このHDDはクラスタサイズ16Kbでフォーマットされました(以下で確認できるように、データベースのページサイズと同じです)。
ソフトウェア
デスクトップコンピュータであるため、オペレーティングシステムはWindows XP Professional SP3、32ビットです。実際にテストを実行するために、TPCベースのツールキットのローダーを使用しました(http://ibdeveloper.com/tests/tpc-c/からダウンロードできます。バイナリとソースの両方が利用可能です)。
ローダーは、実際のシナリオで挿入されるのと同じ方法でデータを挿入することに注意してください。レコードは、テーブルごとではなく、複数のマスター-ディテール-サブディテールテーブルに挿入され、データベース内(および物理ディスク領域)に配置されます。
表2:ソフトウェア
| ソフトウェア | バージョン |
| オペレーティングシステム | Windows XP Professional SP3、32ビット |
| Firebird | 2.1.3 SuperServer(スナップショット) |
| ローダー | tpcベースのテストからのカスタムローダー |
計画
この実験には非常に単純な計画がありました:
- データベースを作成し、インデックスなしで1Tbのデータをロードする
- 主キーと適切なインデックスを作成する(実際にはデータベースサイズは1Tbを超える)
- データベース統計を収集する
- いくつかのSQLクエリを実行し、データベースのパフォーマンスを評価する
データベースとFirebirdサーバーの構成
データベースのページサイズは16384バイトで、HDDクラスタと同じです。これにより、ディスクのスループットパフォーマンスを最大化します(1回のI/Oサイクルで1ページを読み書きするため)。
Firebirdの構成では、一時領域用の追加ディレクトリを設定し、640Gbのディスク(約300Gbの空き容量があった)を指定しました。
ロード手順
データはいくつかのステップでこのデータベースにロードされました。ロード操作中、コンピュータは通常のデスクトップとして使用されました(MS Office、Firefox、IBAnalystなど、約8〜12のプログラムが同時に実行されていました)。このタスク専用にハードウェアを割り当てていれば、おそらくもっと速かったでしょう。そのため、これらの値はローエンドの例としてのみ考慮してください。これらは決して最高の結果ではありません。
表3:ロード操作
| |
| 説明 | 値 |
| ロード時間 | 約70時間 |
| 挿入された総レコード数 | 62億 |
| 平均挿入速度 | 24500レコード/秒 |
| 平均レコードサイズ | 146バイト(最小13バイト、最大600バイト) |
| トランザクション | 646489 |
ロードに約4日間を費やし、その後、正確に1Tbサイズ(つまり1 099 900 125 184バイト)のFirebirdデータベースができました。
以下に、FBDataGuardビューアーでのデータベースの成長とトランザクションのダイナミクスを示します:

インデックス
インデックスを1つずつ作成し、その作成時間とソートに使用された一時ファイルの適切なサイズを計測しました。
最大のインデックスは、テーブルORDER_LINE用に作成されました。その主キーには4つのフィールド(Smallint、Smallint、Integer、Smallint)が含まれています。このソートインデックスの一時ファイルは182Gbで、データベース内の最終的なインデックスサイズは29.3Gbでした。
38億レコードのテーブルのインデックスでも深さが3であることは興味深いです。ページサイズが16384バイトだったため、このテーブルの主キーを使用したデータ検索にはオーバーヘッドがありません。
統計
その後、データベース統計を収集しました。これには7時間32分45秒かかりました。
主要な統計情報を1つのテーブルにまとめ、いくつかのクエリと時間測定を含めました:
表4:1Tbデータベースの統合統計
| テーブル名 | レコード数 | サイズ、GB | select count(*)の実行時間 | インデックス作成時間 | 一時ファイルサイズ、GB | インデックスサイズ、GB |
| WAREHOUSE | 1240 | 0.002 | 0s | 0 | 0 | 0.0 | | ITEM | 100000 | 0.012 | 0.7s | - | - | 0.0 | | DISTRICT | 124000 | 0.017 | 0.7s | 6 | - | 0.0 | | NEW_ORDER | 111600000 | 32 | 20m 00s | 23m 00s | 4.56 | 0.8 | | CUSTOMER | 372000000 | 224 | - | 41m 00s | - | 2.6 | | customer_last | | | | 1h 52m 32s | 12.4 | 2.3 | | fk_cust_ware | | | | 2h 10m 51s | - | 2.3 | | HISTORY | 372000000 | 32 | - | - | - | - | | ORDERS | 372000000 | 25 | 32m 00s | 45m 41s | 15.2 | 2.5 | | STOCK | 1240000000 | 404 | - | 3h 34m 44s | 41.5 | 9.2 | | ORDER_LINE | 3720051796 | 359 | - | 12h 6m 18s | 182.0 | 29.3 |
データベース統計はこちらからダウンロードできます。
無料のFBDataGuard Community Editionビューアを使用してテキストデータを解釈し、データベースのパフォーマンス指標だけでなく、CPUやメモリ消費量も確認できます。
クエリ
まず、いくつかのテーブルに対して**select count(*)クエリを実行しました(上記の表4の4列目を参照)。ご存知のとおり、Firebirdのマルチバージョン性により、テーブル全体に対するselect count(*)**は、すべてのページを訪問する必要があるため、サーバーにとって高コストな操作です。経験豊富なFirebird開発者はselect count(*)を使用しませんが、データベースとハードウェアの全体的なパフォーマンス比率を示すために使用しました。
select countクエリの後、実際のシナリオからのクエリを実行しましたが、正直なところ、その優れた結果に驚かされました。ご自身でご確認ください:
| クエリ | 統計 | 説明 |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id |
PLAN JOIN (WAREHOUSE NATURAL, CUSTOMER INDEX (FK_CUST_WARE)) ------ パフォーマンス情報 —— Prepare time = 15ms Execute time = 79ms Avg fetch time = 6.08 ms Current memory = 272 264 476 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 82 Writes from cache to disk = 0 Fetches from cache = 3 648 |
12400件と372000000件のレコードを持つテーブルの単純な結合で、WHERE条件なし。「Avg fetch time = 6.08 ms」は最初の行を取得するための時間です。 |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ パフォーマンス情報 —— Prepare time = 16ms Execute time = 78ms Avg fetch time = 6.00 ms Current memory = 272 266 148 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 88 Writes from cache to disk = 0 Fetches from cache = 3 656 |
最近のレコードの選択を強制する条件付きの同じテーブルの結合。「Avg fetch time = 6.00 ms」は最初の行を取得するための時間です。 |
| select count(*) from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 Result = 30000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ パフォーマンス情報 —— Prepare time = 0ms Execute time = 453ms Avg fetch time = 453.00 ms Current memory = 272 263 844 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 1 048 Writes from cache to disk = 0 Fetches from cache = 60 024 |
前のクエリのレコード数をカウント |
| SELECT * FROM ORDER_LINE WHERE OL_W_ID = 500 |
Plan PLAN (ORDER_LINE INDEX (ORDER_LINE_PK)) ------ パフォーマンス情報 —— Prepare time = 0ms Execute time = 94ms Avg fetch time = 7.23 ms Current memory = 136 445 536 Max memory = 136 592 176 Memory buffers = 8 192 Reads from disk to cache = 150 Writes from cache to disk = 0 Fetches from cache = 2 402 |
最大のテーブル(38億レコード)へのクエリ。「Avg fetch time = 7.23 ms」は最初の行を取得するための時間です。 |
<br>Plan<br><br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br><br> <br><br>------ パフォーマンス情報 ------<br><br>Prepare time = 0ms<br><br>Execute time = 3s 438ms<br><br>Avg fetch time = 0.01 ms<br><br>Current memory = 136 445 496<br><br>Max memory = 136 592 176<br><br>Memory buffers = 8 192<br><br>Reads from disk to cache = 1 840<br><br>Writes from cache to disk = 0<br><br>Fetches from cache = 598 636<br> |
||
| SELECT * FROM ORDER_LINE WHERE OL_W_ID = 500 |
最大のテーブル(38億レコード)への同じクエリですが、今回はすべてのレコードを取得しました(299245レコード取得)。 | |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) |
Plan PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ パフォーマンス情報 —— Prepare time = 0ms Execute time = 125ms Avg fetch time = 9.62 ms Current memory = 272 270 824 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 91 Writes from cache to disk = 0 Fetches from cache = 3 659 |
1240レコードと3億7200万レコードのテーブルを結合。 |
| select count(*) from WAREHOUSE, customer where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) Result = 59 970 000 |
Plan PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ パフォーマンス情報 —— Prepare time = 0ms Execute time = 13m 4s 718ms Avg fetch time = 784 718.00 ms Current memory = 272 268 532 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 2 332 583 Writes from cache to disk = 0 Fetches from cache = 119 977 902 |
前のクエリのレコード数をカウント |
まとめ
この実験で、Firebirdは以下の結果を示しました:
-
大規模データベースを扱う確固たる能力。適切なハードウェア上で32TBのデータベースを作成・使用することが可能であり、Firebirdは小規模なデータベース(つまり1TB以下)と同様の高いパフォーマンスを発揮すると確信しています。
-
優れたスケーラビリティと驚くほど小さなフットプリント。1TBのデータベースは通常のデスクトップコンピュータで作成され、さらに重要なことに、一般的なクエリの実行に使用できます:数百万のレコードを取得しない場合、クエリの速度は中規模のデータベース(10〜15GB)と同じです。
これはこの実験の終わりではありません:いくつかのクエリを実行し、追加の統計を収集し、近いうちにより詳細なレポートを公開する予定です。どうぞお楽しみに。
連絡先
ご質問やお問い合わせは[email protected]までお送りください。