Foo
열과 ID1, ID2
복합 기본 키가 정의 된 테이블이 있다고 가정 해 봅시다 ID2, ID1
. (현재 테이블 정의에 나타나는 기본 키 열과 반대 순서로 기본 키 열이있는 방식으로 여러 테이블이 정의 된 System Center 제품을 사용하고 있습니다.)
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;
key_ordinal
에서 칼럼 sys.index_columns
쇼들이 복합 기본 키에 선언 된 동일한 순서로 인덱스 컬럼 :
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';
히스토그램은 통계를 동일한 순서로 보여줍니다.
DBCC SHOW_STATISTICS ('Foo',PK_Foo);
그러나 sys.stats_columns
열을 역순 ( 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';
온라인 설명서에 따르면 stats_column_id
"통계 열 집합의 1 기반 서수"이므로 통계 개체의 첫 번째 열이 1 값을 가리킬 것으로 예상했습니다.
이 부분이 버그입니까, sys.stats_columns
아니면 오해입니까?
이 동작은 현재 SQL Server 2005, 2008, 2008 R2, 2012 및 2014 빌드에서 발생 함을 확인했습니다.
sys.stats_columns
다른 상황에서 통계 개체 내 순서를 반영하는 것으로 보입니다 (예 :
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%';
다음은 sys.stats_columns
인덱스에 대한 통계를 위해 올바른 데이터를 반환하는 것으로 보이는 또 다른 예입니다 .
--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
은 그것이 말하는 것을하지 않는 것 같습니다. 인덱스를 백업하고 있기 때문에 인덱스 열 순서를 고수합니다. 통계 개체를보고 있다면index_col()
현재 가장 좋은 옵션 인 것 같습니다