MS SQL Serverのバージンクエリのパフォーマンスを向上させる方法は?


10

ASP.NET Webサイトで、独自の独立したデータキャッシュを実行し、データが長期間変化しないため、同じクエリでSQL Serverに2回クエリする必要がありません。そのSQL Serverへの初回(バージン)クエリのパフォーマンスを改善する必要があります。一部のクエリは、SQL Serverが使用する可能性のある大量のデータを処理しますtempdb。一時テーブル変数や一時テーブルは使用しないので、SQL Serverはtempdb必要なときにいつでもそれ自体を使用することにしました。

私のデータベースサイズは16Gbですが、サーバーマシンで32Gbの物理RAMを使用できます。

MS SQL Serverのキャッシュ戦略は、同じデータを再度ロードする必要がある場合に、同様のクエリのパフォーマンスを向上させるために、RAMにデータを保持しようとすることを理解しています。さらに、tempdbの代わりに使用可能なRAMを使用して、ディスクアクセスを引き起こさずにパフォーマンスを高速化しようとします。

tempdb SQL Serverに何かを格納する必要があるクエリが来て、十分なRAMが利用できない場合、SQL Serverには2つの選択肢があると思います。

1)キャッシュされたデータをアンロードし、tempdbの代わりにスペアRAMを使用してディスクの書き込みを回避する

2)今後のクエリのためにキャッシュされたデータを保持し、tempdbの使用を開始します。これにより、ディスクへの書き込みが遅くなります。

この状況でSQL Serverがどのような選択をするかはわかりませんが、最初の(バージン)クエリのパフォーマンスのみを考慮し、同じクエリをSQL Serverに再度送信することはないため、選択#1をしたいと思います。 (私は同様のクエリを送信する可能性があります)。

このシナリオのSQL Serverキャッシュ戦略は何ですか?

新しいクエリのtempdbの回避と2回目のクエリの速度の間で、RAMの使用量をどのようにバランスさせますか?

SQL Serverを選択#1するように構成することは可能ですか?はいの場合、どのように?

他にどのようにしてすべてのバージンSQLクエリのパフォーマンスを向上させることができますか?

SQL Serverのキャッシュ戦略がわからないので、データベースをRAMディスクに配置します。これにより、SQL Serverが常に#1を選択する場合でも、キャッシュされていないデータを高速で読み込むことができます。SQL Serverが選択肢#2を選択し続けると、SQL Serverが利用可能なRAMを少なくしてより多くのtempdbを使用し始める可能性があります(RAMディスクに16Gbを使用した後は16Gbしか残りません)tempdb

SQL 2008 R2のソリューションに興味がありますが、おそらくSQL 2008、SQL 2005でも同じで、SQL 2000かもしれません。

明確化:

そのボックスで実行されている他のアプリケーションはなく、SQL Server専用です。ウェブサイトは別のボックスで実行されます。

Windows Server 2008 R2 Enterprise 64ビット上のSQL Server 2008 R2 Standard Edition 64ビットです。

読み取り専用クエリのみを実行し、データベースが読み取り専用に設定されています。

すでに良いインデックスがあるとしましょう。この質問は、SQL Serverが選択肢#1と選択肢#2を作ること、それを制御する方法があるかどうか、RAMディスクがバージンクエリの正しい選択を行うのに役立つかどうかについてです。


一時テーブルを作成していなくてもtempdbが使用されていると思うのはなぜですか。個別またはグループ別のテーブルを使用していますか?
darin海峡、

3
32/64ビット?物理的か仮想か?このサーバーはSQL Server専用ですか、それともIISまたは他のアプリも同じボックスで実行していますか?クエリ実行プランの分析を行いましたか?クエリの例や実行計画を投稿できますか?そして、もう1つ幸運なことに... 問題のあるクエリの実行中にKendraのガイドに従ってsp_whoisactiveをログに記録し、出力を投稿してください。
Mark Storey-Smith、

@darinstrait最も可能性の高い説明は、ソートまたはハッシュ流出です。
Mark Storey-Smith、

回答:


7

あなたの質問は基本的に「クエリメモリの付与はどのように機能するのですか?」と言い換えることができます。この件については、SQLサーバーのメモリ許可について理解することをお勧めします。クエリを実行する前に、ソートとハッシュ、およびその他のメモリを大量に消費する操作のためのメモリ許可必要になる場合があります。このメモリ付与は概算です。現在のシステム状態(実行中および保留中の要求の数、使用可能なメモリなど)に基づいて、システムはクエリに必要な量までのメモリ許可を与えます。メモリが許可されると、クエリは実行を開始します(許可を取得する前に、恐ろしい「リソースセマフォ」キューで待機する必要がある場合があります)。実行時にメモリの付与が保証されますシステムによって。このメモリ量は、データページと共有できます(常にディスクにフラッシュできるため)。ただし、他のメモリ使用量と共有することはできません(つまり、「スチール」することはできません)。したがって、クエリがその許可からコミットされたメモリを要求し始めると、エンジンは「戦略#1」と呼ばれるものをデプロイします。データページ、クエリに約束されたメモリを与えるために追い出される(ダーティの場合はフラッシュされる)場合があります。見積もりが正しく、許可が要求されたメモリの100%であった場合、クエリは「スピル」しないはずです。しかし、見積もりが正しくなかった場合(つまり、カーディナリティの見積もりに至るため、統計が古くなっている可能性があります)、またはクエリが要求したすべての許可を得られなかった場合、クエリは「スピル」します。tempdbが登場し、通常はパフォーマンスが向上する時期です。

このプロセスで何かを制御するために自由に使える唯一のつまみは、リソースガバナーです。RGはプールのMIN設定を指定するために使用できるため、特定のワークロード用にメモリを予約して、実際に要求するメモリ許可を取得するために使用できます。もちろん、適切な調査を行った後、減少したメモリ許可原因であることがわかります。もちろん、他のワークロードへの影響が評価された後もです。もちろん、テスト済みです。

では、元の質問に戻りましょう。あなたの調査が正しい場合(非常に大きい場合)、2つの問題を指摘したいと思います。

  • Webサイトのメモリ許可を必要とする本番クエリで実行します。これは大きなノーノーです。メモリ許可は、HTTPリクエストを処理する場所がない分析クエリを示します。
  • クエリはおそらく、要求するメモリ許可を取得するイベントではありません。繰り返しになりますが、Webサイトと同様に、レイテンシが重要なワークロードの場合は、さらに多くの禁止事項があります。

つまり、それはあなたが根本的なデザインと建築上の問題を抱えているということです。Webサイトはレイテンシ主導型であり、OLTPのようなワークロードを作成する必要があります。メモリの付与やクエリへのメモリの負荷はありません。流出は言うまでもありません。分析クエリはオフラインジョブで実行し、前処理された結果を保存して、HTTPリクエストで必要なときにすぐに利用できるようにする必要があります。


@マーク:ほとんどのクエリでは、メモリの付与は必要ありません。少数の演算子(特に、ソートとハッシュ結合)だけが作業バッファーを必要とし、したがって許可を要求します。これは標準の「命名法」です。実行環境とクエリ実行プランを考えているかもしれません。そのすべてのクエリには1つが必要でメモリが含まれています。メモリの付与ははるかに大きい(MB)。次に、見てくださいsys.dm_exec_query_memory_grants:(requested最大)、required(最小)、granted(実際)があります。
Remus Rusanu 2012年

謝罪。クエリごとの最小値が同じメモリクラークから割り当てられた場所からピックアップしましたが、これは誤りでした。
Mark Storey-Smith

それでも、あなたの2つの箇条書きに同意するかどうかはわかりません。あらゆる種類の簡単なソートとハッシュ結合操作では、最低レベルの許可が必要であるため、それらを完全に排除する必要があることを示唆するのは過度に思われます。不十分な許可からtempdbへの流出が危険信号であることは確かに合理的ですが、許可を必要とする操作を全面的に禁止すると、多くの人々が不要なプリエンプティブな最適化パスに設定される可能性があります。
Mark Storey-Smith

OPは、必要なすべてのインデックスがあると主張しています。それが本当であり、ワークロードに目立つほどの十分なメモリ許可(および流出)の問題がある場合、ワークロードはWebサイトには分析的すぎると言えます。最終的には、パフォーマンスの最適化は常に根本的な原因を特定するための調査ゲームです。すべての包括的な声明と禁止は、それらが間違っていることを証明する反例を常に見つけています。OPには、あまりにも分析的なワークロードを作成する設計上の問題がありますか?知りません。そうだと思いますか?私は87.5%の信頼度はイエスだと思います。
Remus Rusanu

@Remus:あなたの推測は良かった、私のWebサイトのクエリは100%分析的です。これにより、ユーザーはUIで任意のクエリを作成して、フィルター、集計、およびグループ化の任意の可能な組み合わせをSQL Serverに送信できます(これにより、当然、インデックス作成は困難になります)。はい、それらを非同期モードで実行して、後で取得できるように結果を保存することもできますが、目的は、クエリを非常に高速に実行して、結果が2〜10秒後にすぐに利用できるようにすることです。また、分析クエリがそのWebサイトの唯一の機能です。 、それらを非同期にすることは、分析的でない他のクエリがある場合にのみ意味があると思います。
alpav

3

言及していないのは、データベースに対して実行されるクエリの種類と、クエリのパフォーマンスを高速化する適切なインデックスがあるかどうかです。

同じボックスで他のアプリケーションが実行されているかどうかも確認する必要があります。ボックスには32 GBのRAMがありますが、データベースサーバーに最大メモリ設定を設定して、人為的な制限を設けていませんか。同じサーバー上で実行されているアプリがある場合、SQLと他のアプリがリソースを競合している可能性があり、SQLはメモリを大量に消費することに注意してください。

SQL Serverはtempdbを内部ソート、ハッシュ結合/集約、またはスプールオペレーターなどに使用します。この動作を制御することはできません。できることは、返されるデータの量を制限することです。

このボックスの待機統計を確認しましたか?SQL Serverがリソースを待機するたびに、SQL Serverは待機リソースを追跡し、その情報を確認すると役立ちます。

Glenn Berryの診断クエリを見てください。これは良いスタートです。

http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspxで言及されているように強制されるパラメータ化も見てください


OK、すでに正しいインデックスがあると仮定しましょう。これは読み取り専用クエリを備えた読み取り専用データベースであり、SQl Serverボックスで実行されている他のアプリケーションがないことを言及するのを忘れていました。
alpav

あなたの統計は最新ですか?読み取り専用データベースは、欠落しているか古くなっている場合、統計を作成できません。データが歪んでいるか、キーに一意の値があるか。この動作を引き起こす可能性のある要因はたくさんあります。
Sankar Reddy、2012年

「この振る舞い」とはどういう意味ですか?何かがおかしいとは言わなかった。特別な状況下でパフォーマンスを向上させたいだけです。SQL Serverはどのような状況でも実行できるように最適化されていますが、私の状況では最善の方法で実行できる場合とそうでない場合があります。SQL Serverを信頼して#1と#2のバランスの取れた選択を行えるかどうかはわかりません。新しいデータを配置するたびに、sp_updatestatsを実行します。
alpav


2
sp_updatestatsを実行しているとき、選択したサンプル比率はどのくらいですか。デフォルトの比率はサンプルであり、インデックスのサイズによって異なります。クエリがほとんど(のみ)の新しいデータをクエリし、sp_updatestatsを実行した場合でも、SQL Serverは実行プランに関して適切な判断を下すことができません。
Sankar Reddy

2

この質問は現在、問題を探す解決策のようになっています。RAMディスクが解決策であり、誰かにその選択を検証してほしいと決めました。申し訳ありませんが、起こりません。

tempdbへの流出を測定して観察した場合は、ほとんどの場合、ソートまたはハッシュ操作とクエリメモリの不足が原因です。処理するデータの量によっては、これは避けられないかもしれませんが、それを回避するためにクエリやインデックス作成を改善することができます。

SQL Serverがメモリを管理する方法とSQL Serverのメモリ管理についての理解を深めるにはバッファ管理ご覧ください。メモリが割り当てられている場所を理解するためにいくつかの基本的なツールとDMVクエリについて説明しました。

他にどのようにしてすべてのバージンSQLクエリのパフォーマンスを向上させることができますか?

これは大きな話題です。クエリを投稿して計画を立てると、的を絞ったフィードバックが得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.