web-dev-qa-db-ja.com

SQL Serverに必要なRAM

500GBを占有するデータベースがありますが、100GBのRAMがあっても、容量が少ないことに気づきました。その理由を見つけるためにグーグルで検索し、いくつかの興味深いクエリを見つけました。クラスター化インデックスを使用しているにもかかわらず非常に大きなテーブルで実行されるクエリがあるため、pleがドロップされます。クエリの前後とクエリが完了した直後にバッファプールの内容を確認しました。クエリで使用されたインデックス用に、またクエリの後に古いインデックスがバッファプールにロードされた後、DBがスペースを解放する必要があるようです。私の質問は、RAM DBに必要なメモリ、それをどのように計算できるか、使用されたすべてのインデックスを一度にメモリに保持できる量にする必要がありますか?または保持されているデータを減らす必要がありますテーブルでは、インデックスが小さくなりますか?

5
whd

大きなインデックス(または、必要に応じて大きなテーブル)をスキャンするたびに、そのデータをディスクからメモリに移動する必要があります。これが発生した場合、バッファープールが他のオブジェクトからのデータを保持していて、ディスクから読み取っているページに対応できるだけの十分な空き領域がない場合、何かを破棄する必要があります。

PLEが低いということは、このプロセスが頻繁に発生し、バッファープールがスラッシングし、I/Oサブシステムに負荷がかかることを意味します。

それを改善するいくつかの方法:

  1. RAMを追加します。簡単で、最近はそれほど高価ではありません。問題を実際に解決するわけではありませんが、受け入れ可能な短期的な解決策になる可能性があります。どれくらいのRAM?データベースのアクティブな部分を保持するのに十分です。それがどれだけかはあなただけが知ることができます。 SQL Server および Windows のすべてのバージョン/エディションが同じ量のRAMを使用できるわけではないので、それによって制限されないようにしてください。
  2. 一部のデータを削除します。そこにあるすべてのデータが必要ですか?
  3. より小さいインデックスを作成します。つまり、クエリをカバーする列の最小セットをインデックスに含めます。大きなスキャンは、小さなインデックスでより高速に動作し、必要なRAMが少なくなります。トレードオフは、ディスクで使用される領域が増えることと、テーブルを更新するときに実行する操作が増えることです。
  4. フィルターされたインデックスを作成します。一般的な非選択条件(例:active=trueまたは類似のもの)でフィルター処理を頻繁に行う場合、フィルター処理されたインデックスは、インデックスのサイズを減らすのに役立つ場合があります。これは、アプリケーションにもいくつかの影響を及ぼします(これを機能させるためのSETオプションの制限)。
  5. 圧縮を使用します。データはディスク上とメモリ内の両方で圧縮されるため、ROW/PAGE圧縮はメモリ消費を削減する方法の1つです。 Enterprise Editionが必要になり、CPUをあきらめる必要がありますが、巨大なオブジェクトの場合は、それだけの価値があります。
  6. 正しいデータ型を使用します。intが十分なときに(n)char(n)varcharまたはtinyintよりも多く使用すると、ディスク領域だけでなくバッファプール領域も無駄になります。これには文字データ型と数値データ型が含まれます。データ列に正しい型/サイズ/精度/スケールを使用していることを確認してください。
7
spaghettidba

私は100GBのRAMメモリを持っていますが。

SQL Serverのどのバージョンとエディションを使用していますか? 2012年(およびそれ以前)の標準版は64Gbまでしか使用しないため、これらを使用している場合、この状況でメモリを追加する意味はほとんどありません。それ以降のリリースでも、標準版の制限は128Gbです。もちろん、企業を運営している場合、そのような制限はありません。

クラスター化インデックスを使用しているにもかかわらず非常に大きなテーブルで実行されるクエリがあるため、pleがドロップされます。

「クラスター化インデックスを使用していても」-それがscanningクラスター化インデックスの場合、基本的にテーブル全体を読み取っているため、クエリがすべての行のすべての列を考慮して結果を生成する必要がない限り、クエリのリファクタリングや関連するテーブルのインデックス作成方法の更新の可能性。詳細がなければ、それ以上のことはできません(理想的には、インデックスとキーを含むテーブル定義、クエリ、見積もりと実際のクエリプラン)、それ以上はできません。

私の質問は、どのくらいRAMメモリにDBが必要ですか、どのように計算できますか?

これは残念ながら難しい質問です。多くの大きな記事がこの主題について書かれています。

使用されているすべてのインデックスを一度にメモリに保持できる量にする必要がありますか?

経験則は、「一般的なワーキングセットが常にメモリ内にあるのに十分」(多くの場合、「メモリ内で使用されるすべてのインデックス」はほぼ同じことを意味します)であり、通常は一般的なワーキングセットの小さな倍数です。 -しかし、これを逆に考えることもできます。たとえば、同じ量のデータに対して、「必要な一般的なワーキングセットを減らすために、インデックスとクエリをより適切に設計できますか?」ということです。完全なインデックスまたはヒープをスキャンしない場合は、ロット全体がRAMに残っていることを確認する必要はありません。

または、インデックスが小さくなるように、テーブルに保持されているデータを減らす必要がありますか?

データが必要な場合は、データも必要です。古いデータを別のDBにアーカイブすることもできますが、これは通常、実行時の問題ではなく、フルバックアップなどのスペースと処理時間を節約するために行われます。適切に動作するアプリを備えた適切に設計されたインデックス付きDBは、通常、これを必要としません。

3
David Spillett

既存の回答とは別に、SQL ServerでRAMがどのように使用されているかを知る必要があります。

100 GBのボックスがあるとしますRAM SQL Server専用です。SQLServerはこれをすべて利用しますRAMこれを制限してSQLを制限すると言いますサーバーの最大メモリを94 GBに...

この94 GBのメモリがどのように使用され、このメモリを使用する主なコンポーネントは何かを理解しましょう。

-DMVの下で実行すると、この94GB RAMを使用できるコンポーネントの合計リストが表示されます

select (sum(pages_kb))/1024 as 'sizein_mb',type as 'clerkttype'
from sys.dm_os_memory_clerks
group by type
order by (sum(pages_kb)*128)/1024 desc

sizein_mb   clerkttype
92469779    MEMORYCLERK_SQLBUFFERPOOL
2889702 CACHESTORE_OBJCP
786610  CACHESTORE_SQLCP
274682  OBJECTSTORE_LOCK_MANAGER
221056  MEMORYCLERK_SOSNODE
206657  USERSTORE_SCHEMAMGR
186691  USERSTORE_TOKENPERM
125331  USERSTORE_DBMETADATA
84542   MEMORYCLERK_SQLSTORENG

上記の出力からわかるように、現在メモリを使用しているコンポーネントが多数あり、さらに Buffer Pool がメモリの最大のコンシューマであり、次に plan Cache が続きます。 =、ロックマネージャー。

注意すべき重要な点の1つは、上記のコンポーネントがメモリを相互に調整することです。たとえば、プランキャッシュによって使用されるメモリはバッファプールから盗まれるので、プランキャッシュがアドホックプランでいっぱいになると、バッファプールのメモリは少なくなります。操作すると、ページがディスクに強制的に書き込まれます。

RAMがどのように使用されるかを理解しました。6GB RAMあなたが残した方法を使用できるオブジェクトは何ですかOSを利用しています。

以下は、6 GBのメモリを取得するコンポーネントです

1.Os itself
2.Linked servers
3.Extended stored procs
3.third party dlls or addins
4.Database email
4.SSIS
5.SSRS
6.SSAS and so on

SQLがRAMをどのように使用するかを理解したので、問題が発生した場合でも簡単に決定を下し、トラブルシューティングを開始できます。

3
TheGameiswar