データベースサイズ-MDFが大きすぎますか?


10

約2.9TbのデータをホストするSQL Server 2005データベースを維持しています(2 x 1.45Tb-RAWスキーマとANALYSISスキーマがあるため、基本的にデータの2つのコピーが取り込まれます)。リカバリモデルはシンプルで、6 .ldfGBです。

何らかの理由で、.mdf7.5Tbです。現在、ANALYSISテーブルには2〜3列しか追加されておらずNVARCHAR(MAX)、私が誤って理解している可能性があるため(間違っている場合は修正してください)、追加のスペース割り当てを引き起こしている可能性がある列は多くありません。これは、データベースを圧縮した直後です。その前は、約9 TBでした。何かご意見は?

そして、追加の質問がある場合はお知らせください-私はデータベース管理と最適化の取り組みに非常に慣れていません(私は通常、仕事のこの側は行いません:))。

どうもありがとう!

アンドリヤ


マルクに感謝-この質問をそこに移動する方法はありますか、それとも再投稿する必要がありますか?

乾杯-おそらくご

回答:


11

サイズの見積もりで、インデックスが使用するスペースの量を考慮に入れましたか?また、(N[VAR]CHARではなく[VAR]CHAR)マルチバイトとして設定されたテキストフィールドがあり、入力ファイルがUTF-8または1文字あたり1バイトのプレーンの場合、ストレージ要件は最大2倍になります。さらに、テーブルにクラスター化されたキー/インデックスがある場合、このサイズはすべての行のクラスター化されたキー値を含むため、テーブルのその他すべてのインデックスに影響することに注意してください(テーブルにNCHAR(10 )INTはどうしたらキーとそのあなたはまた、行あたり16のバイトを無駄にデータページ内の行あたりの余分な16バイトを使用しているだけでなく、あなたのクラスタ化キー/インデックスでそのテーブルの上に他のすべてのインデックス

また、一部のスペースは割り当てられますが、未使用です。DBエンジンが削除後に割り当てられたスペースを残して、そのテーブルの新しいデータにすぐに再び使用できるようにするため、または挿入と削除のパターンが多くのページだけを残したためですいっぱい。

以下を実行できます。

SELECT o.name
     , SUM(ps.reserved_page_count)/128.0 AS ReservedMB
     , SUM(ps.used_page_count)/128.0 AS UsedMB
     , SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o  
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id  
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0  
GROUP BY o.name  
ORDER BY SUM(ps.reserved_page_count) DESC

スペースをとっているテーブルを簡単に確認できます。

またEXEC sp_spaceused、そのDB内で実行すると、2つの結果セットが返されます。1つ目は、ファイルシステムにデータファイル用に割り当てられたスペースの合計とその量を示し、2つ目は、割り当てられたスペースのどの程度がデータページ、インデックスページに使用されているか、または現在使用されていないかを示します。

sp_spaceused 特定のオブジェクトが使用するスペースも返すため、これをループして分析用のテーブルを作成できます。

-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
                     , CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sDataKB    , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sIndexKB   , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sUnusedKB  , ' KB', '') AS BIGINT) 
                FROM #tTmp
DROP TABLE #tTmp 
-- DO SOME ANALYSIS 
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB),  iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables

上記のコードは、すべてのテーブルサイズを1つのリストに加えて、合計の1行を出力します。必要に応じて、さまざまなシステムビュー(上記の最初のクエリsys.objectsと同様にsys.dm_db_partition_stats使用されます。詳細については、http://technet.microsoft.com/en-us/library/ms177862.aspxを参照)を使用して、次のような詳細を取得できます。各インデックスで使用されるスペース。


データファイルには、3つのクラスの未使用領域があります。

  1. 何にも割り当てられていないもの(これは、sp_spaceusedオブジェクトが指定されていない最初の結果セットに表示されます)
  2. オブジェクトに割り当てられている(予約されている)が現在使用されていない(これは、sp_spaceusedの出力の「未使用」カウントに示されます。
  3. 部分的に使用されているページでロックされている(これは、すべてが単一のページチャンクに割り当てられており、1ページが8,192バイト長であるため、使用されるように見えます)。これは検出/計算が困難です。これは、次の2つの要因の組み合わせによるものです。
    • ページを分割します。データが追加されると、ページが部分的に空のページになることがよくあります(ストレージエンジン常にページコンテンツを正規化できますが、これは非常に非効率的です)。行が削除されると、ページコンテンツは自動的にパックされません(再度可能ですが、余分なI / O負荷は、一般、それだけの価値はありません。
    • ストレージエンジンは、行を複数のページに分割しません(これは、行あたり8,192バイトの制限が発生するページサイズとともに)。行が固定サイズであり、それぞれが1,100バイトを取る場合、そのテーブルに割り当てられた各データブロックの少なくとも492バイトを「無駄」にします(7行は7,700バイトを消費し、8番目は適合しないため、残りのバイトは適合しません)使用しないでください)。行が広いほど、これは悪化する可能性があります。可変長の行(完全に固定長の行よりもはるかに一般的です)を持つテーブル/インデックスは、一般にかなり良いです(しかし、問題の計算が簡単ではありません)。
      ここでのもう1つの注意点は、大きなオブジェクト(TEXT列、[N]VARCHAR(MAX) 特定のサイズを超える値など)は、ページ外に配置されるため、メイン行データで8バイトを使用して、他の場所にあるデータへのポインターを保持するため)、行あたり8,192バイトの制限を超える可能性があります。

tl; dr:予想されるデータベースサイズの見積もりは、最初に想定するよりもはるかに複雑です。


デビッド-細かい対応に感謝します!私は現在データベースを分析しています。データベースサイズに影響を与える要因を理解するには、あなたとケネスの両方の回答が非常に役立ちました。私は常に効率(データの取り込みとデータの使用の両方)に関心があります。皆さんから提供された情報は非常に貴重です。
Andrija_Bgd 2013

6

sp_spaceusedデータベースで実行してみてください。例として、次を返します:

reserved           data               index_size         unused
------------------ ------------------ ------------------ ------------------
6032 KB            2624 KB            1664 KB            1744 KB

データベース上で実行するには、データベースだけUSEを実行しsp_spaceusedます。

それでも大量の未使用領域が表示される場合は、もう一度縮小してみてください。時々私はそれが複数の試みをとることを見つけます。また、データベース全体ではなく、個々のファイルを縮小するほうがうまくいく場合もあります。ただし、2.9Tbのデータと別の4 + Tbのインデックスがある場合、7.5TBはかなり妥当です。各テーブルのスペース(データとインデックス)の量を感じたい場合sp_spaceusedは、テーブルレベルでも実行できます。次のコマンドを使用して、データベース内のすべてのテーブルで実行できます。

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

公平な警告sp_msforeachtableは文書化されていませんが、サポートされておらず、テーブルを見逃すことがわかっています。一方、私はそれでかなりの運がありました。

そのすべてがあなたのデータベースはあなたの予想される成長に応じて一定の割合の空き容量を持っているべきだと言われています 基本的には、6か月から数年の成長に見合うだけのスペースを確保する必要があります。また、autogrowth設定が自分の状況に適しているかどうかを確認することもできます。特に、データベースのサイズを考えると、%を使用したくないautogrowth


ありがとうございました!私はsp_spaceusedを使用しましたが、実際のデータが実際に示された量のスペースを占めるように見えます。ロードされたフラットファイルの実際のサイズを考えると、奇妙に聞こえるかもしれません...インデックスは小さいです(私は持っていません)私の場合、ヘルプよりも邪魔になるので、追加のテーブルを作成しました)ですから、実際のテーブルだけが大きいと思います...ご協力ありがとうございます。
Andrija_Bgd 2013

データベースはフラットファイルよりも多くのスペースを使用します。行とテーブルの構造にはある程度のオーバーヘッドがあり、ページ構造のためにある程度の無駄があります。
ケネスフィッシャー

-1

SQL Management Studioを使用して、1。データベースを右クリックし、次に[タスク]-> [縮小]-> [ファイル]をクリックします。

以下を示すダイアログが表示されます。現在割り当てられているスペースb。利用可能な空き容量+(%free)

%Freeが50%を超える場合は、ファイルを圧縮することを検討してください。このヒットは90%にも達しました。ファイルを縮小することにした場合は、通常、現在割り当てられているスペースよりも2ギガまたは3ギガ多く設定します。私のデータベースのほとんどは50ギガ未満です。したがって、ファイルがはるかに大きい場合は、10ギガバイト大きくすることができます。私は通常、データベースを別のサーバーに移動する場合にのみ縮小について心配します。SQLページの縮小の問題に関するすべてを読むことができます。

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