À moins que je ne comprenne mal le but de la colonne, le code suivant indique qu'un changement de la structure de l'index cluster ne change pas la position ordinale ( stats_column_id
) de la colonne dans le DMV sys.stats_columns . (Testé dans 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;
Cependant, les vecteurs de densité indiquent un changement dans la colonne de tête de l'objet index / statistiques. Est-ce un malentendu fondamental de ma part? Si oui, comment trouver la première colonne d'un objet de statistiques à l'aide de DMV?
Versions testées de SQL Server: 2008R2, 2014
sql-server
statistics
dmv
swasheck
la source
la source
key_ordinal
est l'ordre des colonnes d'index (je viens de le découvrir). cependant, la documentation sur sys.stats_columns semble indiquer que stats_column_id est la position ordinale, mais je pourrais lire ceci complètement faux.INDEX_COL()
même si je me souviens vaguement que quelqu'un a noté que ces fonctions d'aide n'étaient peut-être pas la meilleure idéeRéponses:
Par tous les comptes, cela peut être un comportement bogue dans le DMV sys.stats_columns. Cela semble poser des problèmes lorsqu'une statistique est mise à jour via l'index parent. Je pense que cela est dû au mécanisme avec lequel les statistiques sont mises à jour lors d'un changement de contrainte.
Si vous créez une statistique manuellement et souhaitez ensuite modifier les colonnes, vous devez d'abord supprimer et recréer, ce qui force les métadonnées à être mises à jour dans le DMV en question. Dans l'opération que vous avez démontrée, il semble y avoir une situation dans laquelle les métadonnées ne sont en aucun cas mises à jour (DBCC *, CHECKPOINT, redémarrage du serveur, mise à jour des statistiques via la modification de l'index parent, etc.) une fois la modification effectuée. D'après mes tests initiaux, je ne peux trouver qu'un seul cas où les métadonnées sont correctement mises à jour, c'est le scénario de suppression et de recréation.
Vous pouvez jeter un œil à l' élément Connect sur la question et voter de manière appropriée. Il y a un travail autour de la requête qui y est publiée mais son mécanisme est basé sur la correspondance du nom d'index avec le nom de statistique et en utilisant les métadonnées d'index.
la source
J'avais le même problème en essayant de reproduire la façon dont les autres récupèrent les informations d'index à partir des vues sys.dm dans SQL Server. Je ne pouvais tout simplement pas comprendre l'ordre des colonnes dans l'index.
Voici un script que j'ai créé pour déterminer l'ordre des colonnes dans un index donné pour une table donnée:
La colonne
key_ordinal
de la table sys.index_columns est l'ordre dans lequel les colonnes sont stockées dans l'index.Il n'y a pas de
key_ordinal
colonne pour lesys.stats_columns
tableau. La colonnestats_column_id
réplique simplement laindex_column_id
colonne de l'objet auquel elle fait référence.Il y a une légère différence dans le libellé de l'article sys.stats_columns (Transact-SQL) pour la colonne
stats_column_id
:... et dans l'article sys.index_columns (Transact-SQL) pour la
key_ordinal
colonne:Je pense que
index_column_id
(sys.index_columns) etstats_column_id
(sys.stats_columns) sont équivalents l'un de l'autre et que seule la table sys.index_columns a une colonne de commande, à savoirkey_ordinal
.la source