sys.stats_columnsは間違っていますか?


28

FooID1, 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

Books Onlineでは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アイテムを提出する必要がありますか?私にはバグがあるようです。
マックスヴァーノン

6
@ MaxVernon、swasheskがここに
ジェームズ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には反映されません。

マックスバーノンとジェームスルポルトは、彼らのコメント/励ましに基づいて同意しているようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.