Actian Zen の SQL 利用とパフォーマンス向上策
Actian Zen は、約40年前に「Btrieve」という製品名でリリースされ、当時はローレベルの関数(Btrieve API)によるアクセスのみが提供されており、SQL アクセスが実装されたのは、1997年リリースの Pervasive.SQL v7 からです。
初期の頃からのパッケージベンダー様のシステムでは、今でも Btrieve アクセスのみで実装されているものが多くあります。ローレベル関数による処理は動作が軽く、旧バージョンとの互換性も担保されているため、旧来の資産を継続使用し続けることに問題はありません。Btrieve の特性が活きるシステム(例えば、「キーを使用して一意のデータを高速に抽出する」物流倉庫の仕分けシステムや POS など)では、今なお多くのベンダー様が Btrieve API による DB アクセスを採用しており、その有効性を示していますが、一般的な販売管理や生産管理といった業務系システムでは、テーブル間のリレーションを使用したデータの参照や任意の軸による集計などは SQL で実装した方が何かと便利な場面が多いでしょうし、技術者リソースとしても SQL スキルを持った人材の方が集めやすいでしょう。
Btrieve API によるアクセスで実装されているアプリケーションを SQL アクセスでも使用できるようにするためには、SQL 用のテーブル情報を作成し、Btrieve データファイルに紐づけます。
(SQL 用のテーブルと Btrieve データファイル紐づけ方法)
(例)Member.mkd というデータファイルに会員テーブル(ID INT, Name CHAR(20), Birth DATE, Sex CHAR(4), Tel CHAR(12)) を作成して紐づける場合。
⇒ CREATE TABLE "会員" IN DICTIONARY USING 'MEMBER.mkd' ( ID BIGINT, Name CHAR(20), Birth DATE, Sex CHAR(4), Address CHAR(40), Tel CHAR(12));
CREATE TABLE 文で、DDF(Data Definition File)を編集する「IN DICTIONARY」と実ファイルを関連づける「USING」キーワードを使って、 テーブル作成と DDF 登録を同時に行うことができます。
※Actian Zen の管理ツール「DDF Builder」を使用して手動でテーブル情報を作成、DDF 登録することもできます。(詳細は以下をご参照下さい)
https://www.agtech.co.jp/products/actian/psql/pdf/Actian_Zen_v15_API2SQL.pdf
SQL でアクセスする場合、SQL 文を解釈する SRDE(SQL Relational Database Engine)が Btrieve ファイルへの I/F となる MKDE(Micro Kernel Database Engine)を経由してデータにアクセスします。
【Btrieve API と SQL のアクセスルート】
Btrieve API の高速性は、プログラムに記述された関数から直接ローレベルでデータにアクセスする、このシンプルな構造によってもたらされています。一方、SQL では幾つかの処理ステップを踏み、最終的に MKDE 経由でデータアクセスするため、Btrieve でアクセスしていたときよりもパフォーマンスが落ちる可能性が否めません。
パフォーマンスを上げるのに一番早いのは、高速処理が可能な 1次キャッシュを活用することです。Actian Zen のデフォルトでは物理メモリの 60% をキャッシュとして使用し、そのうち 20% を 1次キャッシュとして使っています。この 1次キャッシュ設定を高く設定することで処理の高速化を図ることができます。
(キャッシュの設定方法)
- Zen Control Center の左ペインの「サーバ」(この例では MyComputer という名前)の右クリックで「プロパティ」を開き、「パフォーマンスチューニング」を選択。
- 「キャッシュ割当サイズ(MB)」が 1次キャッシュ、「MicroKernelメモリ使用量」が 2次キャッシュを示す。デフォルトでは 1次キャッシュが物理メモリの 20% の値、2次キャッシュが同 60%(パーセンテージ)でセットされている。
【検証】
以下のような環境でキャッシュ設定を変えたときのパフォーマンスを比較してみます。
(マシンスペック)
- CPU:intel core i5-9400(2.9Ghz/6コア)
- 実装RAM:32GB
- ストレージ:SSD(WDCPCSN520)475GB
(データとシステム)
- ある地域住民の所得税額と地域ごとの減税率を計算して最終課税額(FINAL_TAX)を登録する。
- データファイルサイズ:17GB(データサイズ量増し目的で200カラムのダミーデータを追加)
*住民テーブル(1000万行)
*減税率テーブル(62行)
(サンプル SQL)
- 新宿区の 20歳から 29歳までの区民情報を抽出する。(約15万件)
→ SELECT * FROM "住民" WHERE CITY = '新宿区' AND AGE BETWEEN 20 AND 29 - 減税率テーブルから新宿区の減税率を参照し、新宿区民の最終課税額を算出し、住民テーブル上に更新する。(約172万件)
→ UPDATE 住民SET FINAL_TAX = INCOME_TAX – INCOME_TAX*(SELECT RATE/100 FROM 減税率 A WHERE 住民.CITY_CD = A.CD) WHERE CITY = '新宿区'
(結果)
・1次キャッシュ:1.6GB、2次キャッシュ:60(%)*デフォルト設定
処理時間 | |
---|---|
SELECT | 0:00:00.313 |
UPDATE | 0:15:32.967 |
・1次キャッシュ:16GB、2次キャッシュ:0(%)
処理時間 | |
---|---|
SELECT | 0:00:00.288 |
UPDATE | 0:03:01.637 |
1000万件から 15万件を抽出する SELECT 文では大きな差は見られませんでしたが、172万件を計算・更新する UPDATE 文では 1次キャッシュをデータファイルサイズと近似する値(デフォルトの 10倍)に設定したことで 1/5 の速度に改善されました。1次キャッシュの活用がパフォーマンスに大きな影響を与えることが分かります。
通常のデータベース運用においては、不規則に読み込まれるデータがキャッシュされていくため、キャッシュの効果が出にくい場合もあると思います。そこで最初から全てのデータをキャッシュに読み込んでおき、大方の SQL リクエストに対応できるようにしておくこともできます。Windows のコマンドプロンプトで、対象ファイルに対して「butil -cacheファイル名」で命令すると、ファイル内容をキャッシュに読み込むことができます。
・1次キャッシュ:16GB +butil -cache コマンドによる事前読み込み
処理時間 | |
---|---|
SELECT | 0:00:00.544 |
UPDATE | 0:01:02.147 |
172万件の UPDATE 文においてはさらなる時間短縮が見られ、デフォルト設定時に比べて 1/15 の速度になりました。なお、このときのキャッシュに読み込めるデータ量は Zen Control Center で設定した 1次キャッシュの値が前提になります。試しにデフォルトのキャッシュ設定で butil -cache を実行してみます。
・1次キャッシュ:1.6GB +butil -cache コマンドによる事前読み込み
処理時間 | |
---|---|
SELECT | 0:00:00.812 |
UPDATE | 0:06:14.503 |
事前読み込みをしない場合(15分32秒)の 1/2 以下の速さにはなりますが、1次キャッシュを増やした場合よりも劣る結果となりました。
以上の検証から 1次キャッシュの調整と butil -cache コマンドによる事前読み込みの効果が高いことが分かりました。1次キャッシュに設定する値は管理ツール「Monitor」を活用して大方の目安を確認することができます。「リソース使用状況」の「使用中データ(MB)」の「ピーク値」にはデータベースを起動してから同時に開いたファイルのサイズ合計が表示され、当該データベースが通常運用において使用しているファイルサイズを類推できます。また、「Micro Kernelセッション」タブの「ディスクアクセス数」と「キャッシュアクセス数」からディスクとキャッシュそれぞれの I/O 数を確認できます。これらの値とマシンが使用する他のサービスでのメモリリソースを勘案しながら、できるだけ 1次キャッシュで処理をカバーできるように値を設定します。
(Monitor ツール ~ 使用するデータファイルサイズの確認)
(Monitor ツール ~ ディスクアクセス/キャッシュアクセス数の確認)
メンテナンスなどでシステムを止めるタイミングがあれば、ファイルの最適化(デフラグ)とともにキャッシュ設定を見直してみてはいかがでしょうか?