JMDC TECH BLOG

JMDCのエンジニアブログです

地味にパフォーマンスチューニングを繰り返した話

皆さん、こんにちは。データ基盤開発部の柳下です。

JMDCでは、全国の契約先健康保険組合様からお預かりした情報を元にデータベースを構築しています。累積母集団数は約1,500万人(2022年9月時点)で、過去からの情報も蓄積しているため、健保加入者の情報だけでも、10数億単位のレコードを保持しています。その10数億単位のレコードを処理するため、DWHのアプライアンス製品を利用しています。

オンプレミスの宿命で、ハードウェア保守期限に伴うシステム移行が避けられません。今回は、アプライアンス製品の切り替えに伴い、従来の処理方式を見直して、地味にパフォーマンスチューニングを繰り返してきた経験談をご紹介します。

このブログでお伝えしたいこと

  • データベースのパフォーマンスチューニングについて、基本的な考え方はどのプラットフォームにおいても共通する。
  • ただし、最適なアプローチはデータベースプラットフォームによって異なる。

データベースパフォーマンスチューニングの基本的なアプローチ

さて突然ですが、皆さんは、データベースのパフォーマンスチューニングと言うと、どんな方法を思い浮かべますか?

プラットフォームによって選択肢は異なるとは思いますが、一般的な RDBMS であれば、例えば以下のような方法が挙げられると思います。

  • 統計情報の定期的な取得
  • ヒント句を使用した実行計画の変更、あるいは、固定化
  • インデックスの見直し
  • テーブル定義の見直し
  • 処理方式の見直し(一度に扱うデータ量、SQL … etc

DWH アプライアンス製品であろうとも、基本的なアプローチは変わりません!

ですが、ベースとなるデータベースプラットフォームによって、最適な選択肢がこうも違うのかと実感させられています。

まず開発段階でぶつかった壁

元々、健保加入者の情報を扱う DWH では、以下のような処理を行っていました。

  1. 日次バッチ処理で、データを洗い替え
  2. 週次バッチ処理で、別 DWH に転送

当該処理は PostgreSQL ベースの DWH 製品上で実行されていました。

ハードウェア保守期限に備え、製品選定していた当時、後継製品が予定されていませんでした。そこで、PoC を経て、Db2 ベースの製品を選択しました。

従来の処理方式

 

従来、週次転送処理は1~2時間程度で終わっていました。

ところが、方式をそのままに移行したところ、倍以上の時間がかかることが判明しました。実行計画に問題がある訳でもなく、単純に処理に時間がかかる。となると、統計情報、実行計画の見直しでは切り抜けられません。テーブル定義の見直しも難しかったことから、処理するレコードの量を見直しました。

転送対象レコードを判別できる仕組みを追加し、差分転送するように変更した結果、処理時間は何とか運用可能な範囲に収まり、無事にリリースを迎えることができました。

修正後の処理方式

リリース後にぶつかった壁

ところが、リリース後、日次バッチ処理にかかる時間が、データ量の増加に伴いリニアに伸び始め、やがて、運用に支障が出始めました。これは、移行前には無かったことでした。内部処理の違いで、データ量が処理時間に及ぼす影響が異なるのでしょう

そこで、日次の処理においても、処理するレコードの量を見直しました。

上述の変更内容を拡張し、対象レコードを判別できるようにした結果、処理時間はむしろ移行前よりも短縮することができるようになりました!

更に修正後の処理方式

運用開始後、しばらく経ってからぶつかった壁

日次・週次処理にテコ入れしたことで、一年程度は安定運用できていました。

ところが、日次の洗替処理が急に長時間化するようになりました。通常、夜間に1時間程度で終わっているはずの処理が、翌日の日中になっても終わっていないことがしばしば発生するようになりました。厄介なのは、毎日長時間化する訳でもなく、処理時間が安定しなかったことで、週次処理の日に重なると最悪です … 。

そこで、ひとまず洗替対象テーブルの統計情報の再取得を明示的に行うようにしました。洗替対象テーブルは、日中に更新される量が多いことが分かっていたためです。

幸い、それから1カ月程度の間は再び安定するかのように見えました … が、またしても急に長時間化するようになりました。

次に、改めて調査したところ、長時間化した時とそうでない時とで、実行計画に差異があることまで突き止めました(最初からやっておけよって話ですが)。

ですが、Db2 はヒント句に関する公開情報が少なく、実行計画の固定化が困難でした(そもそも、異常時の負荷が高く、実行計画の取得、比較ができなかった)。そこでやむなく、処理内容を見直すことにしました。

詳しくは述べられませんので、簡単に言うと、従来、with 句と from 句の副問合せで取得していたデータを、それぞれセッション一時表として切り出しました。

これ以降、実行計画が安定するようになり、処理の長時間化は発生していません。

現在の処理方式

おわりに

以上、本当に地味なパフォーマンスチューニングを繰り返してきただけのお話ですが、如何でしたでしょうか。

JMDC では、オンプレミスだけでなく、クラウドも活用しながら種々のデータベースプラットフォームを駆使して、日々様々なデータを処理しています。それぞれのプラットフォームに応じて最適な方法を考えるのもデータベースエンジニアの醍醐味ではないでしょうか?

少しでも興味を持って頂けたのでしたら、幸いです!