web-dev-qa-db-ja.com

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

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

何らかの理由で、_.mdf_は7.5Tbです。現在、ANALYSISテーブルには2〜3列の追加列しかなく、NVARCHAR(MAX)列は多くありません。割り当て。これは、データベースを縮小した直後です。その前は、約9 TBでした。何かご意見は?

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

どうもありがとう!

アンドリヤ

10
Andrija_Bgd

サイズの見積もりで、インデックスが使用するスペースの量を考慮に入れましたか?また、マルチバイト(_N[VAR]CHAR_ではなく_[VAR]CHAR_)として設定されているテキストフィールドがあり、入力ファイルがUTF-8または1文字あたり1バイトの場合、ストレージがプッシュされます最大2倍の要件。さらに、テーブルにクラスター化されたキー/インデックスがある場合、すべての行のクラスター化されたキー値が含まれているため、このサイズはテーブル上の他のすべてのインデックスに影響することに注意してください。 (テーブルにINTと同じNCHAR(10)キーがあり、それがクラスター化されたキー/インデックスである場合の極端な例を示すために、データページの行ごとに余分な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
_

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

また、そのDB内で_EXEC sp_spaceused_を実行すると、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負荷は通常 far の価値があります)。
    • ストレージエンジンは、行を複数のページに分割しません(これは、行あたり8,192バイトの制限が発生するページサイズとともに)。行が固定サイズであり、それぞれが1,100バイトを取る場合、そのテーブルに割り当てられた各データブロックの少なくとも492バイトを「無駄」にします(7行は7,700バイトを消費し、8番目は適合しないため、残りのバイトは適合しません)使用しないでください)。行が広いほど、これは悪くなる可能性があります。可変長の行(完全に固定長の行よりもはるかに一般的です)を持つテーブル/インデックスは、一般にかなり良いです(しかし、問題を計算するのは簡単ではありません)。
      ここでのもう1つの警告は、ラージオブジェクト(特定のサイズを超えるTEXT列、[N]VARCHAR(MAX)の値など)であり、ページ外に配置されるため、8バイトを占めるだけです。別の場所にあるデータへのポインタを保持するメイン行データ)なので、行あたり8,192バイトの制限を超える可能性があります。

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

11
David Spillett

データベースで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を使用したくありません。

6
Kenneth Fisher