こんにちは、篠原です。
Webアプリケーションのバックエンドで動き、あらゆるデータを管理しているDBですが、
急にクエリ実行が遅くなった…!
という状況が再現しては、原因究明に苦心することがたびたびありました。
クエリ実行が急に遅くなったときのアプローチとしては、
など、様々な要因があります。
そして、その原因をはっきりと突き止めることが難しく、トライ&エラーを繰り返すことになります。
アプローチの1つであるクエリのチューニングに関しては、Web上でたくさんの事例が紹介されていますので、
今回は「DB自体の運用管理に問題がある場合」として、盲点だった実例をご紹介します。
私が経験した事例は、1日1回大量のデータを取り込み、格納用のテーブルにINSERTやUPDATEを繰り返し行う要件で、
その取り込み処理が規定時間内に完了せず、データを参照できない、というものでした。
もともと肥大化が避けられない巨大なテーブルであったことから、定期的にデータを削除する運用は決まっていたものの、
その定期削除に至る前に、パフォーマンスに限界をきたしてしまった、という状況です。
統計情報の更新、キャッシュクリアをしても状況は改善せず。
原因は何だったか。
結論としては、その表には圧縮がかかっておらず、データベース上のI/O処理が増加したために発生していることがわかりました。
当該アプリケーションとしては、日次データをさかのぼって参照することができるものの、過去日のデータが参照されることは少ない。
そこで、過去データに該当するパーティションに圧縮をかける運用を行ったことで、
取り込み完了までの時間が劇的に改善したのです。
圧縮をかけることによるデータ参照時のオーバーヘッドはありますが、
1つのテーブルにおけるデータの参照頻度の特性を理解し、参照されるケースの少ないデータに圧縮をかけることによって、
巨大なテーブルに対する処理を最適化することができる、という実例でした。
設計の段階できちんと検討しなければならないですね。
巨大なテーブルを扱う場合は、データの参照頻度を検討した上で、パーティショニングとデータ圧縮の使用を検討しましょう!