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



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

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 步。

我明白了。

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

最新更新