swa*_*eck 15 sql-server statistics dmv
除非我误解了列的用途,否则以下代码表明聚集索引结构的更改不会更改sys.stats_columns DMV 中stats_column_id列的序数位置 ( ) 。(在 AdventureWorks2014、AdventureWorks2008R2 中测试)
select i.name, c.name, ic.column_id, ic.index_column_id
from sys.indexes i
join sys.index_columns ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
join sys.columns c
on i.object_id = c.object_id
and ic.column_id = c.column_id
where i.name = 'PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID'
order by ic.key_ordinal;
select sh.name,s.name, c.name, c.column_id, sc.column_id, sc.stats_column_id
from sys.stats s
join sys.stats_columns sc
on s.object_id = sc.object_id
and s.stats_id = sc.stats_id
join sys.columns c
on s.object_id = c.object_id
and sc.column_id = c.column_id
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
where s.name = 'PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID'
order by sc.stats_column_id;
dbcc show_statistics('[Person].[BusinessEntityAddress]','PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID') with density_vector;
ALTER TABLE [Person].[BusinessEntityAddress] DROP CONSTRAINT [PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID]
GO
ALTER TABLE [Person].[BusinessEntityAddress] ADD CONSTRAINT [PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID] PRIMARY KEY CLUSTERED
(
AddressID ASC,
[BusinessEntityID] ASC,
[AddressTypeID] ASC
)
GO
select i.name, c.name, ic.column_id, ic.index_column_id
from sys.indexes i
join sys.index_columns ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
join sys.columns c
on i.object_id = c.object_id
and ic.column_id = c.column_id
where i.name = 'PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID'
order by ic.key_ordinal;
select sh.name,s.name, c.name, c.column_id, sc.column_id, sc.stats_column_id
from sys.stats s
join sys.stats_columns sc
on s.object_id = sc.object_id
and s.stats_id = sc.stats_id
join sys.columns c
on s.object_id = c.object_id
and sc.column_id = c.column_id
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
where s.name = 'PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID'
order by sc.stats_column_id;
dbcc show_statistics('[Person].[BusinessEntityAddress]','PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID') with density_vector;
Run Code Online (Sandbox Code Playgroud)
但是,密度向量表示索引/统计对象的前导列发生了变化。这是我的根本误解吗?如果是这样,我将如何使用 DMV 找到统计对象的前导列?
经测试的 SQL Server 版本:2008R2、2014
我在尝试重现其他人从 SQL Server 中的 sys.dm 视图检索索引信息的方式时遇到了同样的问题。我只是无法弄清楚索引中列的顺序。
以下是我创建的脚本,用于确定给定表的任何给定索引中的列顺序:
SELECT s.name AS Schema_name,
o.name AS Table_Name,
i.type_desc AS Index_Type,
i.name AS Index_Name,
c.name AS Table_Column,
i.fill_factor AS Indx_Fill_Factor,
ic.key_ordinal AS [Key_ordinal (IDX Column_Order)],
ic.index_column_id AS Index_column_id,
stc.stats_column_id AS Stats_Col_ID,
-- Additional info for each joined table
-- comment out what you don't need
-- 2 lines at a time
--
-- '| table object -->', -- column seperator
-- o.*,
-- '| schema object-->', -- column seperator
-- s.*,
'| index info-->', -- column seperator
i.*,
'| sys index info -->', -- column seperator
si.*,
'| indx cols info -->', -- column seperator
ic.*,
'| tab cols info -->', -- column seperator
c.*,
'| idx stats info -->', -- column seperator
st.*,
'| idx stats columns info -->', -- column seperator
stc.*
FROM sys.objects AS o
JOIN sys.schemas AS s
ON s.schema_id = o.schema_id
JOIN sys.indexes AS i
ON i.object_id = o.object_id
JOIN sys.sysindexes as si
ON si.[id] = i.object_id
AND si.indid = i.index_id
JOIN sys.index_columns AS ic
ON ic.object_id = i.object_id
AND ic.index_id = i.index_id
JOIN sys.columns AS c
ON c.object_id = ic.object_id
AND c.column_id = ic.column_id
JOIN sys.stats AS st
ON st.object_id = i.object_id
and st.stats_id = i.index_id
JOIN sys.stats_columns AS stc
ON c.column_id = stc.column_id
AND stc.stats_id = st.stats_id
AND stc.[object_id] = o.[object_id]
WHERE 1=1
--and i.type <> 1 -- Exclude Clustered Indexes. 0 = Heap; 1 = Clustered Index, 2 = Non-Clustered Index
AND s.name != 'sys' -- Exclude sys items
and o.name = 'BusinessEntityAddress'
AND i.name = 'PK_BusinessEntityAddress_BusinessEntityID_AddressID_AddressTypeID'
ORDER BY
o.object_id,
i.index_id,
ic.key_ordinal
Run Code Online (Sandbox Code Playgroud)
sys.index_columns 表中的列key_ordinal是列在索引中存储的顺序。
key_ordinal该表没有一列sys.stats_columns。该列stats_column_id只是复制index_column_id它引用的对象的列。
sys.stats_columns (Transact-SQL)文章中该列的措辞略有不同stats_column_id:
一组统计列中从 1 开始的序数。
...在文章sys.index_columns (Transact-SQL)中该key_ordinal列:
键列集中的序号(从 1 开始)。
我认为index_column_id(sys.index_columns) 和stats_column_id(sys.stats_columns) 彼此等效,并且只有 sys.index_columns 表具有排序列,即key_ordinal。