2017-06-25 3 views
2
このビュー

のインデックスのサイズを見つけるためにどのようにテーブル値関数

は、テーブル、 ビュー、またはとして索引または表オブジェクトのヒープあたりの行が含まれていることを語句がある

In article about sys.indexesテーブル値関数

このようなインデックスのサイズを調べることに興味がありました。

だから私は、インデックスを持つ関数を作成:レコードはsys.indexesでもあり

enter image description here

enter image description here我々は新しいインデックスの名前を見ることができます。ここ

create function fIndexSize() 
returns @res table 
(
    object_id int   not null 
, name  varchar(128) not null 
, primary key (object_id) 
) 
as 
begin 
    insert into @res 
    select object_id, name 
    from sys.objects 
    where object_id > 255 
return 
end 

通常、次のクエリを使用してインデックスのサイズを取得します。

select 
     o.schema_id 
    , o.object_id 
    , o.name 
    , o.type_desc 
    , sum (a.total_pages) * 8.00/1024/1024 as TotalSpaceGB 
from sys.objects o 
inner join sys.indexes i on o.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 
where (o.name = 'fIndexSize' or i.name like 'PK__fIndexSi%') 
group by o.schema_id, o.object_id, o.name, o.type_desc 

今回は何も返されませんでした。

誰も私にこのようなインデックスのサイズを見つける方法をアドバイスできますか?

答えて

1

テーブル値関数の結果は、データベースの固定テーブルに格納されません。クエリの実行中にオンザフライで生成されます。

はい、あなたはあなたのインデックスプロパティを指示sys.indexesの行、タイプ(クラスタ化されたか否か)など、is_primary_key、is_uniqueなど

を有するが、該当する行がsys.partitionsおよび​​に存在しません。だからあなたのクエリは何も返しません。内部結合を左結合と置き換えると、NULLの1行がTotalSpaceGBと表示されます。

したがって、ドキュメントは正しいです。ドキュメントでは、テーブル値関数に行が​​であるとは言わない。

この関数を呼び出すたびに、異なる行数が返されることがあります。この一連の行は、クエリが実行される前に存在せず、クエリが終了しても存在しません。

sys.partitionsと​​はこのインデックス(PK__fIndexSi...)で空です。

私はオプティマイザが舞台裏で一時テーブルを作成することを見ることができましたクエリ

select * from fIndexSize() 

の実際の実行計画を見ました。まあ、どこかに行を格納しなければならず、それらはTempDBに格納されます。

​​からtempdbを使用して選択を実行する必要があります。その後、私はTempDBのに対してクエリを実行した

plan explorer

temp table sizes

+0

それを区別するために、私はXXXXで列名を選択しましたマルチステートメントのテーブル値関数は、 'TF '型のsys.objectsに格納されていますが、あなたが言ったように、それはマテリアライズされていないので、スペースの割り当てはありません。クエリ内部結合は、sys.indexesなどに行がないためオブジェクトを省略します。 –

+1

@DanGuzman、少しの実験の後で、テーブル値関数の結果セットがtempdbで実現されていることを確認しました。そのサイズは 'sys.allocation_units'を介しています。私は本当に忙しいサーバー上の問題の一時テーブルの名前を把握する方法を知りません。 –

+0

私は、OPが各関数呼び出しの一時的なスペースを必要としていたことを理解していませんでした。 TVF自体に結びついているのではなく、実行コンテキストごとのスペース。 –

4

はいすることができます

は、最初に私は、一時テーブルの名前を見るためにSQL Sentryの計画Explorerを使用しましたこのインデックスのサイズを確認しますが、それは一度のバッチでのみ生きていると考えるべきで、tempdb(テーブル変数のように)で探す必要があります:

create function fIndexSize() 
    returns @res table 
    (
     object_id_xxxx int   not null 
    , name  varchar(128) not null 
    , primary key (object_id_xxxx) 
    ) 
    as 
    begin 
     insert into @res 
     select object_id, name 
     from sys.objects 
     where object_id > 255 
    return 
    end; 

select i.name, 
      c.name, 
      8 * SUM(au.used_pages) as size_kb 
    from tempdb.sys.indexes i 
     join tempdb.sys.columns c 
      on i.object_id = c.object_id 
     join tempdb.sys.partitions as p 
      on p.object_id = i.object_id and p.index_id = i.index_id 
     join tempdb.sys.allocation_units as au 
      on au.container_id = p.partition_id   
    where c.name = 'object_id_xxxx' 
    group by i.name, 
       c.name 

は、私が見つけたインデックスは、我々が探しているものであることを示すために、ここでしか列名を左に行き、よく

関連する問題