sys.stats_columns가 잘못 되었습니까?


28

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_columns

온라인 설명서에 따르면 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%';

더 많은 통계


3
몇 달 전에 같은 질문이 있었지만 삭제했습니다. 미안합니다. 그럼에도 불구하고 stats_column_idin sys.stats_columns은 그것이 말하는 것을하지 않는 것 같습니다. 인덱스를 백업하고 있기 때문에 인덱스 열 순서를 고수합니다. 통계 개체를보고 있다면 index_col()현재 가장 좋은 옵션 인 것 같습니다
swasheck

5
아마도 당신은 이것을 위해 Microsoft Connect 아이템을 제출해야할까요? 버그가있는 것 같습니다.
Max Vernon

6
@MaxVernon, swashesk가 여기에
James L

답변:


5

이것은 오래 지속되는 오류 인 것 같습니다.

swasheck-2015 년 3 월 5 일 게시 :

https://connect.microsoft.com/SQLServer/feedback/details/1163126

MSDN은 sys.stats_columns.stats_column_id는 "통계 열 집합 내의 1 기반 서수"입니다. 그러나 실제로 테이블 정의 순서를 반영하는 것 같습니다. 인덱스 순서 변경은 sys.stats_columns에 반영되지 않습니다.

Max Vernon과 James Lupolt는 그들의 의견 / 격려에 따라 동의하는 것 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.