3

DATALENGTHすべての列で使用せずに、テーブル変数で使用されているスペースを特定するにはどうすればよいですか?

例えば:

DECLARE @T TABLE
(
a bigint,
b bigint,
c int,
d varchar(max)
)

insert into @T select 1,2,3, 'abc123'

exec sp_spaceused @T

ストアドプロシージャを実行するときにテーブル変数が消費するメモリの量を計算しようとしています。

私はこの例で私が行くことができることを知っています:

SELECT DATALENGTH(a) + DATALENGTH(b) + DATALENGTH(c) + DATALENGTH(d)

DATALENGTHしかし、すべてのテーブル列で行う以外の方法はありますか?

4

1 に答える 1

1

テーブル変数のメタデータは、他のタイプのテーブルのメタデータとほとんど同じであるため、のさまざまなシステムビューを調べることで、使用されているスペースを特定できますtempdb

主な障害は、テーブル変数に次のような自動生成された名前が付けられる ことです。#3D7E1B63その名前を決定する簡単な方法があるかどうかはわかりませんobject_id

以下のコードは、文書化されていない%%physloc%%関数(SQL Server 2008以降が必要)を使用して、テーブル変数に属するデータページを判別しDBCC PAGE、関連するを取得しますobject_idsp_spaceused次に、プロシージャから直接コピーされたコードを実行して、結果を返します。

DECLARE @T TABLE
(
a bigint,
b bigint,
c int,
d varchar(max)
)

insert into @T select 1,2,3, 'abc123'
DECLARE @DynSQL nvarchar(100)

SELECT TOP (1) @DynSQL = 'DBCC PAGE(2,' + 
                       CAST(file_id AS VARCHAR) + ',' + 
                       CAST(page_id AS VARCHAR) + ',1) WITH TABLERESULTS' 
FROM @T
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%)


DECLARE @DBCCPage TABLE (
    [ParentObject] [varchar](100) NULL,
    [Object] [varchar](100) NULL,
    [Field] [varchar](100) NULL,
    [VALUE] [varchar](100) NULL
) 
INSERT INTO @DBCCPage
EXEC (@DynSQL)

DECLARE @id int

SELECT @id = VALUE
FROM @DBCCPage 
WHERE Field = 'Metadata: ObjectId'



EXEC sp_executesql N'
USE tempdb

declare @type character(2) -- The object type.  
  ,@pages bigint   -- Working variable for size calc.  
  ,@dbname sysname  
  ,@dbsize bigint  
  ,@logsize bigint  
  ,@reservedpages  bigint  
  ,@usedpages  bigint  
  ,@rowCount bigint  
/*  
 ** Now calculate the summary data.   
 *  Note that LOB Data and Row-overflow Data are counted as Data Pages.  
 */  
 SELECT   
  @reservedpages = SUM (reserved_page_count),  
  @usedpages = SUM (used_page_count),  
  @pages = SUM (  
   CASE  
    WHEN (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  
   ),  
  @rowCount = SUM (  
   CASE  
    WHEN (index_id < 2) THEN row_count  
    ELSE 0  
   END  
   )  
 FROM sys.dm_db_partition_stats  
 WHERE object_id = @id;  

 /*  
 ** Check if table has XML Indexes or Fulltext Indexes which use internal tables tied to this table  
 */  
 IF (SELECT count(*) FROM sys.internal_tables WHERE parent_id = @id AND internal_type IN (202,204,211,212,213,214,215,216)) > 0   
 BEGIN  
  /*  
  **  Now calculate the summary data. Row counts in these internal tables don''t   
  **  contribute towards row count of original table.  
  */  
  SELECT   
   @reservedpages = @reservedpages + sum(reserved_page_count),  
   @usedpages = @usedpages + sum(used_page_count)  
  FROM sys.dm_db_partition_stats p, sys.internal_tables it  
  WHERE it.parent_id = @id AND it.internal_type IN (202,204,211,212,213,214,215,216) AND p.object_id = it.object_id;  
 END  

 SELECT   
  name = OBJECT_NAME (@id),  
  rows = convert (char(11), @rowCount),  
  reserved = LTRIM (STR (@reservedpages * 8, 15, 0) + '' KB''),  
  data = LTRIM (STR (@pages * 8, 15, 0) + '' KB''),  
  index_size = LTRIM (STR ((CASE WHEN @usedpages > @pages THEN (@usedpages - @pages) ELSE 0 END) * 8, 15, 0) + '' KB''),  
  unused = LTRIM (STR ((CASE WHEN @reservedpages > @usedpages THEN (@reservedpages - @usedpages) ELSE 0 END) * 8, 15, 0) + '' KB'')  


', N'@id int',@id=@id

戻り値

name                           rows        reserved           data               index_size         unused
------------------------------ ----------- ------------------ ------------------ ------------------ ------------------
#451F3D2B                      1           16 KB              8 KB               8 KB               0 KB
于 2011-12-19T12:37:02.067 に答える