SQL Serverクエリのパフォーマンスが数日間使用すると低下するという問題を、今から数週間抱えています。さらに、数日おきに、アプリケーションのODBC SQLExecute()
呼び出しからクエリが返されません。
手動で(SQL Server Management Studioで)インデックスを再構築すると、両方の問題が「修正」されます。
ここにいくつかの詳細があります。
同じクエリがしばらくうまく機能する理由を理解するのに苦労していますが、その後、速度が低下し始めますか?
任意のアイデアをいただければ幸いです。
クエリは、いくつかの理由で時間の経過とともに速度が低下し始める可能性があり、インデックスを再構築すると、いくつかの方法で問題を解決できる場合があります。私の経験でより一般的な理由のいくつかを紹介しますが、他の原因も考えられます。私はあなたがこれらの問題の1つに苦しんでいると思います。詳細を取得できるかどうかを確認するために、質問へのコメントとしていくつかの質問もしました。しかし、いくつかの考え:
Statistics Getting StaleSQL Serverは、列とインデックスの統計を維持します。これらは基本的に、データがどのように分散されるかをクエリオプティマイザーに伝えます。この情報は、オプティマイザがデータに適切なアクセス方法(シークとスキャン)を選択し、使用する結合方法を選択する上で重要です。自動統計更新が有効になっている場合(SQLのデフォルト設定..データベースレベル)、これらは再計算されますが、「十分な」データが変更された場合のみです。したがって、テーブルにいくつかの挿入があるが、統計を手動で更新せず、挿入/更新が自動統計更新をトリガーするのに十分でない場合、データ分散の計画が不十分である可能性があります...インデックスはインデックス統計も再計算します私は定期的に手動で統計を手動で更新するジョブを作成します。これはとにかくベストプラクティスです-次回これが発生したときにデータベースでsp_updatestats
を実行し、違いがあるかどうかを確認してください
クエリプランの問題パラメータスニッフィングに悩まされている可能性があります。基本的に、クエリが初めて実行されるときに、1つの値が渡されます。クエリはその値に対して最適化されます。次に、別のクエリプランの恩恵を受ける別の値で実行すると、元のクエリプランで問題が発生し、クエリが遅くなります。アプリの動作が遅い場合-SQL Server Management Studioで同じクエリを実行すると、動作も遅くなりますか? SSMSでは高速であるがアプリでは低速の場合-これは、パラメータースニッフィングを示す良い兆候となる可能性があります。すべてのクエリで、パラメータに関係なく、時間が経過しても全体的に一貫して遅い場合は、ここでは説明しません。この 記事 は、パラメータのスニッフィングについてかなり話します。
メモリ不足/アドホックプランが多すぎますアドホックSQLをSQL Serverに送信しているようです。これにより、特にクエリの実行ごとに個別のプランがある場合は、プランのキャッシュが肥大化することがあります。サーバーのメモリによっては、これも問題の原因となる可能性があります。サーバーにはどのくらいのメモリがありますか?使い捨てプランの問題に関するこのリンクを確認してください。 SQL Server 2005には、この問題に対する優れた解決策がたくさんありますが、あるとしてもありません。 非製品環境でこの問題を再現できる場合、これが再度発生する場合は、非製品環境でDBCC FREEPROCCACHE
を実行することをお勧めします。ご注意ください!本番環境でこれを行うと、これはインスタンス全体の設定になります。データベースのキャッシュに保存されているクエリプランは存在しなくなります。それはあなたがコンパイルのために再び「支払う」必要があることを意味します。同時実行性が高く、システムがビジーな場合、これが問題を引き起こす可能性があります。これが唯一の実際のデータベースであり、とにかくパフォーマンスの問題に苦しんでいる場合は、本番環境でこれを試しても害はありません..他のデータベースがあり、このデータベースでそれを行うには、このブログの投稿で、1つのDBのみをクリアする方法を説明します。
インデックスの断片化-インデックスの断片化がここで実際の問題である可能性がありますが、非常に早く悪化することに驚いています。テーブルが断片化の原因となるキーでクラスター化されていて、多数の挿入がある場合、これが当てはまる可能性があります。メモリとディスクIOの面でパワーが不足している場合は、さらに悪化します。インデックスを定期的に再構築/再編成するジョブを設定するとよいでしょう。上記のコメントのいくつかの質問に対するあなたの回答に基づいて、これの影響を最小限に抑えるために他にすべきことがあるかもしれません。
本番データベースの1つでも同じ問題が発生しました。ハワーバーは少し異なる状況。テーブルは読み取り/書き込みで、約含まれています。 2,000万件以上のレコード。
毎週(週末)にインデックスを再構築しました。これは月曜日の午後まで役立ちました。その後、大量のデータのためにパフォーマンスが低下しました。
テーブルのサイズによっては、サーバーにキャッシュ内の特定の量のレコードセット用に利用可能な特定の量のスペースしかないというメモリの問題になる可能性があります。 (90%未満のバッファキャッシュヒット率)。解決策:SQL Serverインスタンスにメモリを追加すると役立つ場合があります。これにより、バッファキャッシュヒット率が90%を超える可能性があります。その結果、データは物理ドライブからではなくメモリから取得されます。
SQLデータベースエンジンがデータの取得を目的としたクエリを「最適化」していることが原因である場合は、インデックス統計の問題である可能性があります。 (これは私たちの巨大なテーブルの問題でした)。 stasticsは古くなりました。解決策:このテーブルのインデックス統計を毎日更新すると、問題が解決する可能性があります。
あなたの問題が短期的な問題であることを考えると、それはバッファキャッシュヒット率(SQLメモリが少なすぎる)の問題だと思います。 SQLクエリオプティマイザーは、メモリから小さなレコードセットを削除して、より頻繁に取得されるデータに対応します。
いくつかのことが頭に浮かびます。
ODBC接続オブジェクトは各クエリの最後に閉じられ、削除されますか?それ以外の場合、接続プールは増加し続けます。
不足しているインデックスはありますか?動的管理ビューは、そこで何が起こっているかを教えてくれます。