これはそれほど奇妙に思われるわけではありませんが、UIダイアログの一部は完全に最新の情報を持たない可能性があることに注意してください(これがDBCC UPDATEUSAGEのようなものがある理由です)。計算。最後に、ダイアログにはデータベース全体の合計スペースが表示されますが、未割り当てスペースはログではなくデータファイルに対してのみ計算されます。
いくつかを合体させましょう。
- データベースプロパティと縮小データベースは同じことを示しています(とにかく縮小データベースUIにいる必要はありません!)。
- データベースファイルのプロパティは、17 + 75 = 92を示しています。これは、追加前の丸めにより、おそらく1の91.31と同じです。
- 割り当てられたスペースの場合、個々のファイルのシュリンクは、16.38 + 74.94 = 91.32と表示されます。ここでも、おそらく多少の丸めが行われます。
- 使用可能なスペースについては、個々のファイルの縮小が唯一の不一致が疑われる唯一の場所です。これは、UIがデータを取得する場所についてUIに一貫性がなく、これらの場所の一部がDBCC UPDATEUSAGEを必要とするキャッシュの対象となるためです。
ローカルコピーのAdventureWorks2012でこれらのさまざまなダイアログがどのように実行されるかを見てみましょう(このスクリプトから特定の表を拡大しています)。
EXEC sp_spaceused;
これは(最初の結果セットのみ)を返します。
database_size unallocated space
------------- -----------------
1545.81 MB 6.67 MB
基本的にこれを実行します。これは、トレースを介して確認しましたが、データベースプロパティとデータベース縮小ダイアログから実行されたクエリとほぼ同じです(ストアドプロシージャから関連性のない部分を切り分け、数学を表す外部クエリを追加しました) SSMSが表示のために行うこと):
SELECT database_size = DbSize*8.0/1024 + LogSize*8.0/1024,
[unallocated space] = (DbSize-SpaceUsed)*8.0/1024
FROM
(
SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p
join sys.allocation_units a on p.partition_id = a.container_id
left join sys.internal_tables it on p.object_id = it.object_id
) AS x;
これは一致を返します:
database_size unallocated space
------------- -----------------
1545.8125 6.671875
これらのダイアログはすべて、この情報を正しく表示します。データベースのプロパティダイアログ:
[データベースの縮小]ダイアログ:
一方、ファイルの縮小ダイアログでは、少し異なるクエリを実行します(これも、便宜上、切り分け/適応されています)。
SELECT SUBSTRING(name, CHARINDEX('_',name)+1, 4),
[Currently allocated space] = size/1024.0,
[Available free space] = (Size-UsedSpace)/1024.0
FROM
(
SELECT s.name,
CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)*CONVERT(float,8) AS [UsedSpace],
s.size * CONVERT(float,8) AS [Size]
FROM sys.database_files AS s
WHERE (s.type IN (0,1))
) AS x;
また、DMVではなく関数からサイズデータを取得することに加えて、filestream / hekatonなどの新しいファイルタイプの述語は更新されていません。
結果:
Currently allocated space Available free space
---- ------------------------- --------------------
Data 1517 7.9375 -- wrong
Log 28.8125 25.671875 -- wrong
問題はFILEPROPERTY()
関数であり、最新の状態であることが保証されていません(DBCC UPDATEUSAGE(0);
実行後でも、以下を参照)。これは、ダイアログに関する誤解を招く情報で終わります:
ここでも、6.67 MBは実際には正確ではなかったことに注意してください。これは、データベースの合計サイズ(割り当てられたページ数)のみを測定しているため、ログを完全に無視しているためです。
正直なところ、データベースで使用されているスペースの正確なレポートが必要な場合は、さまざまな種類のクエリを実行するミッキーマウスUIの使用を停止してこれを把握し、情報を取得するための縮小ファイルダイアログの使用を停止します。これらは特定のケースで明らかに古いデータの問題の影響を受けます。信頼できるソースに対して実際のクエリを実行します。これが私が好むものです:
DECLARE @log_used DECIMAL(19,7);
CREATE TABLE #x(n SYSNAME, s DECIMAL(19,7), u DECIMAL(19,7), b BIT);
INSERT #x EXEC('DBCC SQLPERF(LogSpace);');
SELECT @log_used = u FROM #x WHERE n = DB_NAME();
DROP TABLE #x;
DECLARE @data_used DECIMAL(19,7);
SELECT @data_used = SUM(a.total_pages)*8/1024.0
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id;
;WITH x(t,s) AS
(
SELECT [type] = CASE
WHEN [type] IN (0,2,4) THEN 'data' ELSE 'log' END,
size*8/1024.0 FROM sys.database_files AS f
)
SELECT
file_type = t,
size = s,
available = s-CASE t WHEN 'data' THEN @data_used ELSE @log_used END
FROM x;
このクエリは、見慣れたはずの3つの数値と、見慣れないはずの1つの数値を返します。
file_type size available
--------- ----------- ----------
data 1517.000000 6.6718750
log 28.812500 17.9008512
DBCC SQLPERFは、実行後など、スペースの使用に関する問題が多少発生しやすいことに注意してください。
DBCC UPDATEUSAGE(0);
上記のクエリは代わりにこれを生成します:
file_type size available
--------- ----------- ----------
data 1517.000000 8.0781250
log 28.812500 17.8669481
sp_spaceused
これでも、一致する数値が生成されます(1545.81 MB / 8.08 MB
)。ただし、これもデータファイルで使用可能なスペースのみであり、データベースプロパティとデータベースの縮小ダイアログも「正確」です(ただし、ファイルの縮小ダイアログはまだです)オフ- まったくFILEPROPERTY()
影響を受けていないようですUPDATEUSAGE
):
ああ、また、Windowsエクスプローラーがこれらのファイルをどのように考えているかも示しているので、MBを決定するために行われた計算に関連付けることができます。
もちろん、これがどれほど正確である必要があるかは、情報をどのように処理するかによって異なります。