追加コスト 0 で行う SQL Server のパフォーマンス改善・ボトルネック解消 その6
こんにちは、naginoです。
重要性、汎用性、効果について考慮せずに思いつくまま書き連ねる本シリーズも、いつの間にか 6 回目です。
ぶっちゃけ、設計者が設計段階でお金がかかるパフォーマンス関連の事項を、適切な余裕を持たせて設計していれば、運用段階で予算 0 でパフォーマンス改善に苦しむことも無いわけで、そもそも設計を云々、予算を云々としてしまえばそれまでなのですが、なかなかそうも行かない現実も多いわけですよね。
また、設計者は設計者で、パフォーマンスに関連する事項を全て適切に、というのはなかなか困難でして、いつか機会があればそちらも考えてみたいところです。
さて、今日は統計、統計情報について考えて見ます。
SQL Server はコストベースのオプティマイザを使用しているため、コストが推測できる必要があります。
そのため、テーブルの列毎に、値の分布の傾向(統計情報)が必要になります。
まあ、統計情報が無くても全行取得すれば値の分布の傾向は把握できますが、それをやってしまうと時間がかかりすぎるため、サマリともいえる統計情報を使用します。
さて、この統計情報ですが、データの追加や更新が行われると実体と乖離していくため、適宜統計しなおしています。
色々条件などもありますが、初期設定では概ね以下の頻度で自動更新されます。
● 500 行以下のテーブルでは、500 回データが更新される都度
● 500 行より多い場合、500 + (前回統計情報取得時の行数の20%) 回データが更新される都度
ということは、バッチなどで大量のデータ更新を行うと、その途中で統計情報の自動更新が行われます。
一方で、600 行のテーブルでは 620 回データ更新が行われると統計情報の更新が行われるため、統計情報と全く一致しない状態でも更新されないことがありえます。
また、統計情報の更新はデータの一部をサンプリングして取得する必要があり、負荷がかかります。
一方で実態と乖離した統計情報ではオプティマイザがパフォーマンスが良くない実行プランを選択することがありえます。
このため、テーブルの更新処理の傾向や処理傾向に応じて以下の対応をとることで、パフォーマンスが改善することがあります。
● 夜間バッチなどの大量更新作業中は自動更新を停止し、終了後に一括更新
● 更新頻度がそれほど高くないテーブルは夜間に一括更新
ただ、統計情報のメンテナンスを怠るとオプティマイザが適切な実行プランを選択できなくなるので、パフォーマンスが劣化します。
自動更新は有効にしたまま、夜間に必要に応じて手動更新するというのが無難ではあります。
まあ、実際のところ、統計情報関連のパフォーマンス面のトラブルは、適切なメンテナンスが行われていなかったというケースが多いので、個人的にはあまり触らないほうが良いと思います。
バッチによる大量更新の際は、場合によってはある程度効果があるのですけれども・・・。