データベース内のすべてのテーブルのサイズを取得する


1271

かなり大きなSQL Serverデータベースを継承しました。含まれるデータを考えると、予想よりも多くのスペースを占めるようです。

各テーブルが消費しているディスク上の容量を簡単に判断する方法はありますか?


どの役割にアクセスできますか?あなたはDBAですか、それともWebホスト、クライアントなどで管理されていますか?
Rob Allen


@RobAllen私はデータベースへの完全なアクセス権を持っているので、任意の役割を必要とするスクリプトで十分です。
エリック、


Azureの場合、これ
Irf

回答:


2594
SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255 
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    TotalSpaceMB DESC, t.Name

7
ばかげた質問ですが、このクエリが行ロックを引き起こす可能性はありますか?
GEMI 2011

7
インデックスもスペースを使用し、インデックスが使用するスペースの量は、以下のクエリで確認できます。
Jens Frandsen

6
スクリプトにフィルターインデックスに関する問題があります。特定のテーブルのフィルターインデックスごとに、結果にそのテーブルの名前を含む追加の行が表示されます。これらの追加行のそれぞれの「RowCounts」は、フィルターされたインデックスの1つがカバーする行の数に対応します。(Sql2012)
Lukacs

37
@Todd:そのように順序付けしたい人もいれば-テーブル名で注文したい人もいます
好き

12
テーブルがパーティション分割されている場合、何が起こっているかを示すことなく、テーブルが複数回表示されます。選択リストにp.partition_numberを追加するか、SUM(p.Rows)を実行してグループから削除することができます。
PRMan

561

使用している場合は、SQL Server Management Studioの代わりにクエリを実行しているの(SSMS)を、(私の場合には重複行を返された)あなたは実行することができ、標準のレポートを。 

  1. データベースを右クリック
  2. 移動レポート>標準レポート>表により、ディスクの使用状況

注:これを正しく機能させるには、データベースの互換性レベルを90以上に設定する必要があります。http://msdn.microsoft.com/en-gb/library/bb510680.aspxを参照してください


54
Management Studio 2012では、次のことを実行できます。ビュー-オブジェクトエクスプローラーの詳細(F7)。オブジェクトエクスプローラーの[テーブル]に移動します。詳細でヘッダーを右クリックし、列のサイズを選択します。
ValGe 2014年

3
SSMS 2012の新機能を助言してくれたことに感謝しています。したがって、私たちは古いTSQLの方法でそれを実行しました:)
GoldBishop '16年

3
信じられないかもしれませんが、時々単なる人間(開発者)がこの情報を見たいと思っている場合があります。組み込みのレポートを使用する権限がありませんが、受け入れられた回答でTSQLを実行できます。:) FYI(ところで、私はまだあなたの答えを支持しました)
Andrew Steitz

8
Azure SQLに存在しないようです:-(
Simon_Weaver

1
私はそれが深刻ではないことを知っていますが、どうか、疎外されたグループをエンジニアリングとテクノロジーから遠ざけてください。この推論の行はどこでも繰り返されています。両方を学ぶ必要がありますが、時間を節約するユーティリティを使用して、よりスマートに、より速く動作するように人々を懲らしめるべきではありません。(SSMSは「スローダウンユーティリティ」のように見えることがありますが...:X)個人的には表形式データの読み取り値がGUIでより明確になっていますが、Microsoft製のツールはすべてのUI関連の例外です。
ジュリア

102

sp_spaceusedを使用すると、テーブル、インデックス付きビュー、またはデータベース全体で使用されているディスク領域に関する情報を取得できます。

例えば:

USE MyDatabase; GO

EXEC sp_spaceused N'User.ContactInfo'; GO

これは、ContactInfoテーブルのディスク使用情報を報告します。

これをすべてのテーブルに一度に使用するには:

USE MyDatabase; GO

sp_msforeachtable 'EXEC sp_spaceused [?]' GO

SQL Serverの右クリックの[標準レポート]機能からディスク使用量を取得することもできます。このレポートにアクセスするには、オブジェクトエクスプローラーでサーバーオブジェクトから移動し、データベースオブジェクトに移動して、任意のデータベースを右クリックします。表示されるメニューから、[レポート]、[標準レポート]、[パーティション別のディスク使用量:[データベース名]]の順に選択します。


3
sp_msforeachtableSSMSでを使用すると、System.OutOfMemoryExceptionテーブルが多数ある場合に簡単にトリガーされる可能性があります。そのため、一時テーブルを使用して結果を保存することをお勧めします。
syneticon-dj 2014

1
sp_spacedusedで確認できる主な問題は、人間が読める形式でデータを返すように見えることです(たとえば、私の場合は「予約済み」列に「152 KB」が含まれていました)。これは必要に応じてMB / GBに切り替わると思います。これは多くの状況で明らかに役立ちますが、サイズに基づいてロジックを適用する必要がある場合や、値などを比較したい場合には役立ちません。私はそれをオフにする方法を探しましたが、それを見つけることができませんでした(SQL Server 2005を使用しています:()
DarthPablo、

55

別の方法を次に示します。SQLServer Management Studioを使用して、オブジェクトエクスプローラーでデータベースに移動し、[ テーブル]を選択します

ここに画像の説明を入力してください

次に開くオブジェクトエクスプローラの詳細を(押していずれかF7をかへ行く[表示] - > [オブジェクトエクスプローラの詳細)。オブジェクトエクスプローラーの詳細ページで、列ヘッダーを右クリックし、ページに表示する列を有効にします。データは任意の列で並べ替えることもできます。

ここに画像の説明を入力してください


はい、AzureのSSMSには、ローカルバージョンに比べていくつかの機能がありません。
Sparrow

@batmaci Azure SQLデータベースについてコメントしたときに、これがまったく機能していたかどうかはわかりませんが、SSMSの最近のバージョンでは少なくとも部分的に機能しているようです。私にとっては、テーブルメタデータのクエリがタイムアウトしているようですが、タイムアウトする前に、選択したテーブルを含む(確実に)数個(3〜10)のテーブルが返されるようです。テーブルを選択して[更新]をクリックすると、表示されていない場合に必要なテーブルが表示されます。
pcdev

Azureは「実際の」SQLサーバーではありません(ハハ)
リバースエンジニア

私はこれをAzure に使用ました。おかげで(プラス1)
Irf

NirSoft SysExporterなどのユーティリティを使用して、リストをCSVファイルにエクスポートすることもできます:nirsoft.net/utils/sysexp.html
最大

39

いくつか検索した後、すべてのテーブルの情報を取得する簡単な方法が見つかりませんでした。データベースが使用するすべての領域を返す、sp_spaceusedという名前の便利なストアドプロシージャがあります。テーブル名を指定すると、そのテーブルが使用するスペースが返されます。ただし、列は文字値であるため、ストアドプロシージャから返される結果は並べ替えできません。

次のスクリプトは、探している情報を生成します。

create table #TableSize (
    Name varchar(255),
    [rows] int,
    reserved varchar(255),
    data varchar(255),
    index_size varchar(255),
    unused varchar(255))
create table #ConvertedSizes (
    Name varchar(255),
    [rows] int,
    reservedKb int,
    dataKb int,
    reservedIndexSize int,
    reservedUnused int)

EXEC sp_MSforeachtable @command1="insert into #TableSize
EXEC sp_spaceused '?'"
insert into #ConvertedSizes (Name, [rows], reservedKb, dataKb, reservedIndexSize, reservedUnused)
select name, [rows], 
SUBSTRING(reserved, 0, LEN(reserved)-2), 
SUBSTRING(data, 0, LEN(data)-2), 
SUBSTRING(index_size, 0, LEN(index_size)-2), 
SUBSTRING(unused, 0, LEN(unused)-2)
from #TableSize

select * from #ConvertedSizes
order by reservedKb desc

drop table #TableSize
drop table #ConvertedSizes

foreachを使用して上記を確認した後、SPがこのようなものを書くつもりだったので、下にスクロールして少し時間を節約できたことを確認しました。
ブラッド

37
 exec  sp_spaceused N'dbo.MyTable'

すべてのテーブルで使用します。(Paulのコメントから追加)

exec sp_MSForEachTable 'exec sp_spaceused [?]'

5
卑劣 -あなたはテーブルについて何も表示しないものから、exec sp_helpdbそれを表示するものに変更しました-一度に1つのテーブルについてのみ...それはあなたが持っているテーブルとそれらが持っている行の数と方法の概要をあなたに与えません彼らが占める多くのスペース。exec sp_spaceused
marc_s 2011年

4
exec sp_MSForEachTable 'exec sp_spaceused [?]'
Paul

27

上記のクエリは、テーブル(インデックスを含む)によって使用される領域の量を見つけるのに適していますが、テーブルのインデックスによって使用される領域の量を比較する場合は、次のクエリを使用します。

SELECT
    OBJECT_NAME(i.OBJECT_ID) AS TableName,
    i.name AS IndexName,
    i.index_id AS IndexID,
    8 * SUM(a.used_pages) AS 'Indexsize(KB)'
FROM
    sys.indexes AS i
    JOIN sys.partitions AS p ON p.OBJECT_ID = i.OBJECT_ID AND p.index_id = i.index_id
    JOIN sys.allocation_units AS a ON a.container_id = p.partition_id
WHERE
    i.is_primary_key = 0 -- fix for size discrepancy
GROUP BY
    i.OBJECT_ID,
    i.index_id,
    i.name
ORDER BY
    OBJECT_NAME(i.OBJECT_ID),
    i.index_id

特定のテーブルのIndexsize(KB)列の合計がsp_spaceusedのindex_sizeと一致しない理由は何ですか?
Derek

@Derekを追加して彼の答えを修正しましたwhere [i].[is_primary_key] = 0。これでサイズが一致するはずです。
CodeAngry

ありがとうございますが、これも実際にはうまくいきません。(非常に小さい)テストデータベースがあります。対象のテーブルには2つのインデックスがあります。1つの列にプライマリクラスター化インデックスがあり、他の2つの列に非クラスター化インデックスがあります。このクエリは、それぞれが16kBを使用していることを示していますが、sp_spaceusedは、インデックスの合計使用量が24kBであることを示しています。私の混乱の一部はこれです:このクエリを受け入れられた回答の "UsedSpaceKB"と比較しても、実際の違いはわかりません。同じ結合で、sys.tablesの追加がありません。何か不足していますか、またはこのクエリは本質的に壊れていますか?
デレク、

大規模なデータベースがあります。そしてサイズはと一致しsp_spaceusedます。私はGBを測定するため、一致しないいくつかのメガはそれほど多くありません。正確なサイズは気にせず、単なるアイデアです。
CodeAngry

14

SSMSの「テーブルプロパティ-ストレージ」ページにある、まったく同じ数を計算する必要がある場合は、SSMSで行ったのと同じ方法でそれらを数える必要があります(SQL Server 2005以降で機能します... LOBフィールドのあるテーブルでは正しく機能します-「used_pa​​ges」を数えるだけでは正確なインデックスサイズを表示するのに十分ではないためです。

;with cte as (
SELECT
t.name as TableName,
SUM (s.used_page_count) as used_pages_count,
SUM (CASE
            WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
            ELSE lob_used_page_count + row_overflow_used_page_count
        END) as pages
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.tables AS t ON s.object_id = t.object_id
JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id
GROUP BY t.name
)
select
    cte.TableName, 
    cast((cte.pages * 8.)/1024 as decimal(10,3)) as TableSizeInMB, 
    cast(((CASE WHEN cte.used_pages_count > cte.pages 
                THEN cte.used_pages_count - cte.pages
                ELSE 0 
          END) * 8./1024) as decimal(10,3)) as IndexSizeInMB
from cte
order by 2 desc

14

サイズをMBおよびGBで取得するためにテーブルパーティションを処理する@xav 回答への拡張。SQL Server 2008/2012でテスト済み(次の行にコメントを追加is_memory_optimized = 1

SELECT
    a2.name AS TableName,
    a1.rows as [RowCount],
    --(a1.reserved + ISNULL(a4.reserved,0)) * 8 AS ReservedSize_KB,
    --a1.data * 8 AS DataSize_KB,
    --(CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS IndexSize_KB,
    --(CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS UnusedSize_KB,
    CAST(ROUND(((a1.reserved + ISNULL(a4.reserved,0)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS ReservedSize_MB,
    CAST(ROUND(a1.data * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS DataSize_MB,
    CAST(ROUND((CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS IndexSize_MB,
    CAST(ROUND((CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSize_MB,
    --'| |' Separator_MB_GB,
    CAST(ROUND(((a1.reserved + ISNULL(a4.reserved,0)) * 8) / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS ReservedSize_GB,
    CAST(ROUND(a1.data * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS DataSize_GB,
    CAST(ROUND((CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS IndexSize_GB,
    CAST(ROUND((CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSize_GB
FROM
    (SELECT 
        ps.object_id,
        SUM (CASE WHEN (ps.index_id < 2) THEN row_count ELSE 0 END) AS [rows],
        SUM (ps.reserved_page_count) AS reserved,
        SUM (CASE
                WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END
            ) AS data,
        SUM (ps.used_page_count) AS used
    FROM sys.dm_db_partition_stats ps
        --===Remove the following comment for SQL Server 2014+
        --WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized = 1)
    GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN 
    (SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS reserved,
        SUM(ps.used_page_count) AS used
     FROM sys.dm_db_partition_stats ps
     INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
     WHERE it.internal_type IN (202,204)
     GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id ) 
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
--AND a2.name = 'MyTable'       --Filter for specific table
--ORDER BY a3.name, a2.name
ORDER BY ReservedSize_MB DESC

並べ替え順も改善されました。
Pxtl

これが一番の答えになるはずです。
Baodad

14

Azureの場合、これを使用しました:

SSMS v17.xが必要です

私が使用しました。

ここに画像の説明を入力してください

これで、ユーザー Sparrowが述べたように

Databases>を開いて[ テーブル]を選択し、 F7
キーを押します。次 のように表示されます。 row count
ここに画像の説明を入力してください

ここの SSMS はAzureデータベースに接続されています


3
F7は、十分に活用されていません。
cskwg

1
私はこれが存在することを知りませんでした、私は自分自身を少し恥ずかしく思っています:pありがとうございます!
lollancf37

メモリ最適化テーブルに問題があります(この投稿を見た直後にテストしました:)
Amirreza

11

テーブルのパーティション分割を使用しており、レコードが重複しているため、上記のクエリで問題が発生しました。

これが必要な場合は、「テーブル別のディスク使用量」レポートを生成するときにSQL Server 2014によって実行されるクエリを以下に示します。SQL Serverの以前のバージョンでも動作すると思います。

それは魅力のように働きます。

SELECT
    a2.name AS [tablename],
    a1.rows as row_count,
    (a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved, 
    a1.data * 8 AS data,
    (CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
    (CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused
FROM
    (SELECT 
        ps.object_id,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN row_count
                ELSE 0
            END
            ) AS [rows],
        SUM (ps.reserved_page_count) AS reserved,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END
            ) AS data,
        SUM (ps.used_page_count) AS used
    FROM sys.dm_db_partition_stats ps
        WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized = 1)
    GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN 
    (SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS reserved,
        SUM(ps.used_page_count) AS used
     FROM sys.dm_db_partition_stats ps
     INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
     WHERE it.internal_type IN (202,204)
     GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id ) 
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name

SSMSの処理方法に一致し、パーティションを適切に処理するスクリプトをありがとうございます。
マイク

8
-- Show the size of all the tables in a database sort by data size descending
SET NOCOUNT ON
DECLARE @TableInfo TABLE (tablename varchar(255), rowcounts int, reserved varchar(255), DATA varchar(255), index_size varchar(255), unused varchar(255))
DECLARE @cmd1 varchar(500)
SET @cmd1 = 'exec sp_spaceused ''?'''

INSERT INTO @TableInfo (tablename,rowcounts,reserved,DATA,index_size,unused)
EXEC sp_msforeachtable @command1=@cmd1

SELECT * FROM @TableInfo ORDER BY Convert(int,Replace(DATA,' KB','')) DESC

8

Mar_cの回答を少し変更しました。これは、このページに頻繁に戻るため、ほとんどの行が最初になっているためです。

SELECT
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB,
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM
    sys.tables t
INNER JOIN
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN
    sys.schemas s ON t.schema_id = s.schema_id
WHERE
    t.NAME NOT LIKE 'dt%'
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255
GROUP BY
    t.Name, s.Name, p.Rows
ORDER BY
    --p.rows DESC --Uncomment to order by amount rows instead of size in KB.
    SUM(a.total_pages) DESC 

5

これにより、各テーブルのサイズとレコード数がわかります。

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- Get a list of tables and their sizes on disk
ALTER PROCEDURE [dbo].[sp_Table_Sizes]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
DECLARE @table_name VARCHAR(500)  
DECLARE @schema_name VARCHAR(500)  
DECLARE @tab1 TABLE( 
        tablename VARCHAR (500) collate database_default 
       ,schemaname VARCHAR(500) collate database_default 
) 

CREATE TABLE #temp_Table ( 
        tablename sysname 
       ,row_count INT 
       ,reserved VARCHAR(50) collate database_default 
       ,data VARCHAR(50) collate database_default 
       ,index_size VARCHAR(50) collate database_default 
       ,unused VARCHAR(50) collate database_default  
) 

INSERT INTO @tab1  
SELECT Table_Name, Table_Schema  
FROM information_schema.tables  
WHERE TABLE_TYPE = 'BASE TABLE' 

DECLARE c1 CURSOR FOR 
SELECT Table_Schema + '.' + Table_Name   
FROM information_schema.tables t1  
WHERE TABLE_TYPE = 'BASE TABLE' 

OPEN c1 
FETCH NEXT FROM c1 INTO @table_name 
WHILE @@FETCH_STATUS = 0  
BEGIN   
        SET @table_name = REPLACE(@table_name, '[','');  
        SET @table_name = REPLACE(@table_name, ']','');  

        -- make sure the object exists before calling sp_spacedused 
        IF EXISTS(SELECT id FROM sysobjects WHERE id = OBJECT_ID(@table_name)) 
        BEGIN 
               INSERT INTO #temp_Table EXEC sp_spaceused @table_name, false; 
        END 

        FETCH NEXT FROM c1 INTO @table_name 
END 
CLOSE c1 
DEALLOCATE c1 

SELECT  t1.* 
       ,t2.schemaname  
FROM #temp_Table t1  
INNER JOIN @tab1 t2 ON (t1.tablename = t2.tablename ) 
ORDER BY schemaname,t1.tablename; 

DROP TABLE #temp_Table
END

2
あなたのポストコード、XMLまたはデータサンプル場合は、PLEASEテキストエディタでそれらの行をハイライト表示し、「コードサンプル」ボタン(をクリック{ })エディタのツールバーにうまく形式と構文にそれを強調!
marc_s 2011年

4

1つのデータベースですべてのテーブルサイズを取得するには、次のクエリを使用できます。

Exec sys.sp_MSforeachtable ' sp_spaceused "?" '

そして、それを変更してすべての結果を一時テーブルに挿入し、その後一時テーブルから選択することができます。

Insert into #TempTable Exec sys.sp_MSforeachtable ' sp_spaceused "?" ' 
Select * from #TempTable

3

OSQLを使用してコマンドプロンプトから:

OSQL -E -d <*databasename*> -Q "exec sp_msforeachtable 'sp_spaceused [?]'" > result.txt

3

次の手順ですべてのテーブルのサイズをすばやく取得する方法を次に示します。

  1. 指定されたT-SQLコマンドを記述して、すべてのデータベーステーブルを一覧表示します。

    select 'exec sp_spaceused ' + TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE = 'BASE TABLE'
  2. 次に、データベーステーブルのリストをコピーして、新しいクエリアナライザウィンドウにコピーします。

    exec sp_spaceused table1
    exec sp_spaceused table2
    exec sp_spaceused table3
    exec sp_spaceused table4
    exec sp_spaceused table5
  3. SQL クエリアナライザーで、上部のツールバーオプションから[ ファイルへの結果 ] (Ctrl+ Shift+ F選択します

  4. 最後に、上のツールバーから赤いマークが付いた実行ボタンを押します

  5. これで、すべてのテーブルのデータベースサイズがコンピュータ上のファイルに保存されます。

    ここに画像の説明を入力してください


2

marc_sの回答の上にさらにいくつかの列を追加しました。

with fs
as
(
select i.object_id,
        p.rows AS RowCounts,
        SUM(a.total_pages) * 8 AS TotalSpaceKb
from     sys.indexes i INNER JOIN 
        sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id INNER JOIN 
         sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    i.OBJECT_ID > 255 
GROUP BY 
    i.object_id,
    p.rows
)

SELECT 
    t.NAME AS TableName,
    fs.RowCounts,
    fs.TotalSpaceKb,
    t.create_date,
    t.modify_date,
    ( select COUNT(1)
        from sys.columns c 
        where c.object_id = t.object_id ) TotalColumns    
FROM 
    sys.tables t INNER JOIN      
    fs  ON t.OBJECT_ID = fs.object_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
ORDER BY 
    t.Name

1

私の投稿はSQL Server 2000にのみ関連し、私の環境で動作することがテストされています。

このコードは、単一のデータベースだけでなく、単一のインスタンスのすべての可能なデータベースにアクセスします。

2つの一時テーブルを使用して適切なデータを収集し、結果を1つの「ライブ」テーブルにダンプします。

返されるデータは、DatabaseName、DatabaseTableName、Rows(Table内)、data(テーブルのサイズ(KBのように思われる))、エントリデータです(これは、スクリプトを最後に実行した日時を知るのに役立ちます)。

このコードの落とし穴は、「データ」フィールドがintとして格納されないこと(文字「KB」はそのフィールドに保持される)であり、これはソートに役立ちます(ただし、完全に必要というわけではありません)。

うまくいけば、このコードが誰かを助け、時間を節約してくれることを願っています!

CREATE PROCEDURE [dbo].[usp_getAllDBTableSizes]

AS
BEGIN
   SET NOCOUNT OFF

   CREATE TABLE #DatabaseTables([dbname] sysname,TableName sysname)
   CREATE TABLE #AllDatabaseTableSizes(Name sysname,[rows] VARCHAR(18), reserved VARCHAR(18), data VARCHAR(18), index_size VARCHAR(18), unused VARCHAR(18))

   DECLARE @SQL nvarchar(4000)
   SET @SQL='select ''?'' AS [Database], Table_Name from [?].information_schema.tables WHERE TABLE_TYPE = ''BASE TABLE'' '

   INSERT INTO #DatabaseTables(DbName, TableName)
      EXECUTE sp_msforeachdb @Command1=@SQL

   DECLARE AllDatabaseTables CURSOR LOCAL READ_ONLY FOR   
   SELECT TableName FROM #DatabaseTables

   DECLARE AllDatabaseNames CURSOR LOCAL READ_ONLY FOR   
   SELECT DBName FROM #DatabaseTables

   DECLARE @DBName sysname  
   OPEN AllDatabaseNames  

   DECLARE @TName sysname
   OPEN AllDatabaseTables  

   WHILE 1=1 BEGIN 
      FETCH NEXT FROM AllDatabaseNames INTO @DBName  
      FETCH NEXT FROM AllDatabaseTables INTO @TName 
      IF @@FETCH_STATUS<>0 BREAK  
      INSERT INTO #AllDatabaseTableSizes
         EXEC ( 'EXEC ' + @DBName + '.dbo.sp_spaceused ' + @TName) 

   END 

   --http://msdn.microsoft.com/en-us/library/aa175920(v=sql.80).aspx
   INSERT INTO rsp_DatabaseTableSizes (DatabaseName, name, [rows], data)
      SELECT   [dbname], name, [rows],  data FROM #DatabaseTables
      INNER JOIN #AllDatabaseTableSizes
      ON #DatabaseTables.TableName = #AllDatabaseTableSizes.Name
      GROUP BY [dbname] , name, [rows],  data
      ORDER BY [dbname]
   --To be honest, I have no idea what exact duplicates we are dropping
    -- but in my case a near enough approach has been good enough.
   DELETE FROM [rsp_DatabaseTableSizes]
   WHERE name IN 
      ( 
      SELECT name 
      FROM [rsp_DatabaseTableSizes]
      GROUP BY name
      HAVING COUNT(*) > 1
      )

   DROP TABLE #DatabaseTables
   DROP TABLE #AllDatabaseTableSizes

   CLOSE AllDatabaseTables  
   DEALLOCATE AllDatabaseTables  

   CLOSE AllDatabaseNames  
   DEALLOCATE AllDatabaseNames      
END

--EXEC [dbo].[usp_getAllDBTableSizes] 

知っておく必要がある場合は、rsp_DatabaseTableSizesテーブルを次の方法で作成しました。

CREATE TABLE [dbo].[rsp_DatabaseSizes](
    [DatabaseName] [varchar](1000) NULL,
    [dbSize] [decimal](15, 2) NULL,
    [DateUpdated] [smalldatetime] NULL
) ON [PRIMARY]

GO

1

marc_sの答え(受け入れられたもの)単純な拡張として、これは列数を返し、フィルタリングできるように調整されています。

SELECT *
FROM
(

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    COUNT(DISTINCT c.COLUMN_NAME) as ColumnCount,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    (SUM(a.used_pages) * 8) AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN
    INFORMATION_SCHEMA.COLUMNS c ON t.NAME = c.TABLE_NAME
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255
GROUP BY 
    t.Name, s.Name, p.Rows
) AS Result

WHERE
    RowCounts > 1000
    AND ColumnCount > 10
ORDER BY 
    UsedSpaceKB DESC

列テーブルに参加すると、適切なテーブルスペースがなくなります。外部適用が修正されます。
dreamca4er

0

上記の@Markの回答をリフィングし、最新のサイズの統計を強制する@ updateusage = 'true'を追加しました(https://msdn.microsoft.com/en-us/library/ms188776.aspx):

        SET NOCOUNT ON
        DECLARE @TableInfo TABLE (tablename varchar(255), rowcounts int, reserved varchar(255), DATA varchar(255), index_size varchar(255), unused varchar(255))
        DECLARE @cmd1 varchar(500)
        SET @cmd1 = 'exec sp_spaceused @objname =''?'', @updateusage =''true'' '

        INSERT INTO @TableInfo (tablename,rowcounts,reserved,DATA,index_size,unused)
        EXEC sp_msforeachtable @command1=@cmd1 
SELECT * FROM @TableInfo ORDER BY Convert(int,Replace(DATA,' KB','')) DESC

0

以下は、1GBより大きいテーブルをサイズの降順で並べ替えるためのサンプルクエリです。

USE YourDB
GO

DECLARE @Mult float = 8
SET @Mult = @Mult / POWER(2, 20) -- Use POWER(2, 10) for MBs

; WITH CTE AS
(
SELECT
    i.object_id,
    Rows = MAX(p.rows),
    TotalSpaceGB = ROUND(SUM(a.total_pages) * @Mult, 0),
    UsedSpaceGB = ROUND(SUM(a.used_pages) * @Mult, 0)
FROM 
    sys.indexes i
JOIN
    sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
JOIN
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE
    i.object_id > 255
GROUP BY
    i.object_id
HAVING
    SUM(a.total_pages) * @Mult > 1
)
SELECT 
    SchemaName = s.name,
    TableName = t.name,
    c.TotalSpaceGB,
    c.UsedSpaceGB,
    UnusedSpaceGB = c.TotalSpaceGB - c.UsedSpaceGB,
    [RowCount] = c.Rows
FROM 
    CTE c
JOIN    
    sys.tables t ON t.object_id = c.object_id
JOIN
    sys.schemas s ON t.schema_id = s.schema_id
ORDER BY
    c.TotalSpaceGB DESC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.