Чи неправильно стовпці sys.stats_collets?


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_column

Книги Інтернет говорить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%';

morestats

Ось ще один приклад, коли, 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%';

moremorestats


3
У мене було те саме питання кілька місяців тому, але його видалили. Вибач за це. Тим не менш, здається , що stats_column_idin sys.stats_columnsне робить те, що говорить, що робить. Оскільки ви підтримуєте індекс, я дотримуюся порядку стовпців індексу. Якщо ви просто дивитесь на об’єкти статистики, схоже, index_col()це найкращий варіант на даний момент
swasheck

5
Можливо, ви повинні / могли подати для цього елемент Microsoft Connect? Мені здається баггі.
Макс Вернон

6
@MaxVernon, свашеск подав сюди
Джеймс Л

Відповіді:


5

Це здається давньою помилкою:

swasheck - 5 березня 2015 року розміщено:

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

MSDN зазначає, що sys.stats_column.stats_column_id є "порядковим порядком на 1" у наборі стовпців статистики. " Однак, схоже, це фактично відображає порядок визначення таблиці. Зміна порядку індексу не відображається в колонках sys.stats_column.

Макс Вернон та Джеймс Лупольт, схоже, погоджуються на основі своїх коментарів / заохочень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.