行数基于表+索引+统计直方图

时间:2015-06-13 20:50:48

标签: sql sql-server indexing statistics

我只有表格和专栏名称 基于此,我正在寻找按给定列名分组的行数。 是的,我可以跑...

select columnname, count_big(*) from schema.tablename group by columnname

但这意味着占用宝贵的资源。 (IO等)
我想知道,我不能只从统计直方图中收集我需要的东西吗? 毕竟,我需要的只是给定列的一个狭窄的索引 但首先,我需要收集狭窄指数的名称 对于此任务,我运行此查询:

select st.name, si.name, si.index_id, sc.column_id
from sys.tables st
    join sys.indexes si on si.[object_id] = st.[object_id]
    join sys.index_columns sic on sic.[index_id] = si.[index_id] and sic.[object_id] = si.[object_id]
    join sys.columns sc on sic.column_id = sc.column_id and sc.[object_id] = sic.[object_id]
where st.[object_id] = object_id('schemaname.tablename', 'U')
and lower(sc.[name]) = 'columnname'

此查询为我提供了每个索引名称,甚至是复合宽索引。这不是我需要的 您可能会说,这没关系,因为两个索引直方图都将包含该列属性的确切行数 你是对的。

这是一个非常难看的问题 当大约20%的表内容发生变化时,统计信息会自动更新。但我现在想要我的号码。所以我必须运行更新统计信息。在宽索引上运行更新统计信息需要花费时间并占用我想要保存的资源 所以,我需要我的1列窄索引。 (是的,首先真正善用狭窄的索引!)因为这根本不需要时间来更新。

回到我的询问 如果我可以让我的查询显示单个索引包含多少列,我只需将谓词设置为“columncount = 1”。

你知道在上面的语句中添加什么,以显示索引中包含的列吗?

但为什么这一切?
我需要一份报告,显示每个临时表中有多少行是新的,以及我的ETL处理了多少行 我每天都需要这份报告 我一直在寻找的列将有几个不同的值,因此窄索引的直方图将有最多5个步骤。

1 个答案:

答案 0 :(得分:0)

我明白了。

select schema_name(st.schema_id), st.name, si.[name], si.index_id, sc.column_id, ccnt.colcnt
from sys.tables st
    join sys.indexes si on si.[object_id] = st.[object_id]
    join sys.index_columns sic on sic.[index_id] = si.[index_id] and sic.[object_id] = si.[object_id]
    join sys.columns sc on sic.column_id = sc.column_id and sc.[object_id] = sic.[object_id]
    join (select isi.index_id, isi.[object_id], count_big(*) as colcnt
            from sys.indexes isi 
                join sys.index_columns isic on isic.[index_id] = isi.[index_id] and isic.[object_id] = isi.[object_id]
                join sys.columns isc on isic.column_id = isc.column_id and isc.[object_id] = isic.[object_id]
            where isic.is_included_column = 0
            and isi.[object_id] = object_id('schemaname.tablename', 'U')
            group by isi.index_id, isi.[object_id]
            ) as ccnt on ccnt.index_id = si.index_id
where sic.is_included_column = 0
and lower(sc.[name]) = 'columname'
and st.[object_id] = ccnt.[object_id]
and ccnt.colcnt = 1