In article about sys.indexes这个视图有一个短语
包含表格对象的每个索引或堆的行,例如表格, 查看或表值函数。
我有兴趣找到这样一个索引的大小。
所以我用索引创建了函数:
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
在这里我们可以看到新索引的名称:
sys.indexes
中还有一条记录:
通常我会使用此查询获取索引的大小:
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
但这次没有回复。
任何人都可以给我建议如何找到这样一个索引的大小吗?
答案 0 :(得分:4)
是的,你可以找到这个索引的大小,但是你应该认为它只在一个批处理时间内生存,你应该在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
我在这里留下了列名只是为了表明找到的索引是我们要找的,我选择了xxxx的列名来区分它
答案 1 :(得分:1)
表值函数的结果不存储在数据库的永久表中。它在查询执行期间即时生成。
是的,你在sys.indexes
中有一行告诉你索引属性,比如类型(群集或非群集),is_primary_key,is_unique等。
但是,sys.partitions
和sys.allocation_units
中没有相应的行。这就是你的查询什么都不返回的原因。如果使用左连接替换内部连接,则会看到NULL
为TotalSpaceGB
的一行。{/ p>
所以,文档是正确的。文档没有说表值函数在sys.allocation_units
中会有行。
每次调用函数都可能返回不同的行数。在查询运行之前,这组行不存在,并且在查询完成后不存在。
即使在函数执行期间,sys.partitions
和sys.allocation_units
对于此索引(PK__fIndexSi...
)为空。
当我查看查询的实际执行计划时
select * from fIndexSize()
我可以看到优化器在幕后创建临时表。好吧,它必须将行存储在某处,并存储在TempDB中。
因此,您应该使用sys.allocation_units
从tempdb
运行您的选择。
首先,我使用SQL Sentry Plan Explorer查看临时表的名称:
然后我针对TempDB运行了查询: