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

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%';

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 สำหรับสิ่งนี้? ดูเหมือนจะเป็นรถสำหรับฉัน
Max Vernon

6
@MaxVernon, swashesk ยื่นหนึ่งที่นี่
James L

คำตอบ:


5

นี่ดูเหมือนจะเป็นข้อผิดพลาดที่ยาวนาน:

swasheck - 5 มีนาคม 2015 โพสต์:

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.