Angenommen, ich habe eine Tabelle Foo
mit Spalten ID1, ID2
und einem über definierten zusammengesetzten Primärschlüssel ID2, ID1
. (Ich arbeite derzeit mit einem System Center-Produkt, für das mehrere Tabellen auf diese Weise definiert wurden, wobei die Primärschlüsselspalten in der umgekehrten Reihenfolge aufgeführt sind, in der sie in der Tabellendefinition angezeigt werden.)
CREATE TABLE dbo.Foo(
ID1 int NOT NULL,
ID2 int NOT NULL,
CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED (ID2, ID1)
);
GO
-- Add a row and update stats so that histogram isn't empty
INSERT INTO Foo (ID1, ID2) VALUES (1,2);
UPDATE STATISTICS dbo.Foo;
Die key_ordinal
Spalte in sys.index_columns
zeigt die Indexspalten in derselben Reihenfolge, in der sie im zusammengesetzten Primärschlüssel deklariert wurden:
SELECT t.name, i.name, c.column_id, c.name, ic.index_column_id, ic.key_ordinal
FROM sys.tables AS t
JOIN sys.indexes AS i
ON t.[object_id] = i.[object_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 ic.column_id = c.column_id
AND ic.[object_id] = c.[object_id]
WHERE t.name = 'Foo';
Das Histogramm zeigt auch die Statistiken in der gleichen Reihenfolge:
DBCC SHOW_STATISTICS ('Foo',PK_Foo);
Jedoch sys.stats_columns
zeigt die Spalten in der umgekehrten Reihenfolge ( ID1, ID2
).
SELECT s.name, sc.stats_column_id, c.name
FROM sys.stats AS s
JOIN sys.stats_columns AS sc
ON s.stats_id = sc.stats_id
AND s.[object_id] = sc.[object_id]
JOIN sys.columns AS c
ON c.[object_id] = s.[object_id]
AND c.column_id = sc.column_id
JOIN sys.objects AS o
ON o.[object_id] = c.[object_id]
WHERE o.name = 'Foo'
AND s.name = 'PK_Foo';
Die Onlinedokumentation gibt an, dass stats_column_id
es sich um eine "1-basierte Ordnungszahl innerhalb eines Satzes von Statistikspalten" handelt. Ich habe daher erwartet, dass der Wert 1 auf die erste Spalte im Statistikobjekt verweist.
Ist das ein Fehler sys.stats_columns
oder ein Missverständnis von meiner Seite?
Ich habe überprüft, ob dieses Verhalten bei aktuellen Versionen von SQL Server 2005, 2008, 2008 R2, 2012 und 2014 auftritt.
sys.stats_columns
scheint die Reihenfolge innerhalb des Statistikobjekts in anderen Situationen widerzuspiegeln, zum Beispiel:
CREATE TABLE dbo.Foo2(
ID1 int NOT NULL,
ID2 int NOT NULL,
ID3 int NULL,
String VARCHAR(10) NULL,
CONSTRAINT [PK_Foo2] PRIMARY KEY CLUSTERED (ID2, ID1)
);
GO
INSERT INTO Foo2 (ID1, ID2, ID3, String) VALUES (1,2,3,'String');
CREATE STATISTICS ST_Test ON Foo2 (ID3, String);
CREATE STATISTICS ST_Test2 ON Foo2 (String, ID3);
DBCC SHOW_STATISTICS ('Foo2',ST_Test);
DBCC SHOW_STATISTICS ('Foo2',ST_Test2);
SELECT s.name, sc.stats_column_id, c.name
FROM sys.stats AS s
JOIN sys.stats_columns AS sc
ON s.stats_id = sc.stats_id
AND s.[object_id] = sc.[object_id]
JOIN sys.columns AS c
ON c.[object_id] = s.[object_id]
AND c.column_id = sc.column_id
JOIN sys.objects AS o
ON o.[object_id] = c.[object_id]
WHERE o.name = 'Foo2'
AND s.name LIKE 'ST_Test%';
Hier ist ein weiteres Beispiel, in sys.stats_columns
dem die korrekten Daten angezeigt werden, diesmal für Statistiken zu einem Index:
--drop table dbo.Foo3
CREATE TABLE dbo.Foo3(
ID1 int NOT NULL,
ID2 int NOT NULL,
ID3 int NULL,
String VARCHAR(10) NULL,
CONSTRAINT [PK_Foo3] PRIMARY KEY CLUSTERED (ID2, ID1)
);
GO
INSERT INTO Foo3 (ID1, ID2, ID3, String) VALUES (1,2,3,'String');
UPDATE STATISTICS Foo3;
CREATE INDEX IX_Test ON Foo3 (ID3, String);
CREATE INDEX IX_Test2 ON Foo3 (String, ID3);
DBCC SHOW_STATISTICS ('Foo3',IX_Test);
DBCC SHOW_STATISTICS ('Foo3',IX_Test2);
SELECT s.name, sc.stats_column_id, c.name
FROM sys.stats AS s
JOIN sys.stats_columns AS sc
ON s.stats_id = sc.stats_id
AND s.[object_id] = sc.[object_id]
JOIN sys.columns AS c
ON c.[object_id] = s.[object_id]
AND c.column_id = sc.column_id
JOIN sys.objects AS o
ON o.[object_id] = c.[object_id]
WHERE o.name = 'Foo3'
AND s.name LIKE 'IX_Test%';
stats_column_id
insys.stats_columns
nicht scheinen zu tun , was sie sagt , es tut. Da Sie einen Index sichern, halte ich mich an die Reihenfolge der Indexspalten. Wenn Sie sich nur Statistikobjekteindex_col()