版本:SQL Server 2008 R2 企业版。(10.50.4000)
为了评估我们的分区策略,我编写了这个查询来获取针对分区索引的访问方法(在最广泛的意义上,尽管我正在消除堆)。range_scan_count
当我将注意力集中在分区表上时,我相信我需要查看singleton_lookup_count
但很难概念化。
SELECT
t.name AS table_name,
i.name AS index_name,
ios.partition_number,
leaf_insert_count,
leaf_delete_count,
leaf_update_count,
leaf_ghost_count,
range_scan_count,
singleton_lookup_count,
page_latch_wait_count ,
page_latch_wait_in_ms,
row_lock_count ,
page_lock_count,
row_lock_wait_in_ms ,
page_lock_wait_in_ms,
page_io_latch_wait_count ,
page_io_latch_wait_in_ms
FROM sys.dm_db_partition_stats ps
JOIN sys.tables t
ON ps.object_id = t.object_id
JOIN sys.schemas s
ON t.schema_id = s.schema_id
JOIN sys.indexes i
ON t.object_id = i.object_id
AND ps.index_id = i.index_id
OUTER APPLY sys.dm_db_index_operational_stats(DB_ID(), NULL, NULL, NULL) ios
WHERE
ps.object_id = ios.object_id
AND ps.index_id = ios.index_id
AND ps.partition_number = ios.partition_number
and ps.index_id = ios.index_id
and ps.partition_number = ios.partition_number
and s.name <> 'sys'
and ps.index_id <> 0 ;
相关输出(考虑到 SO 表格格式的差距,这是上面查询的前 9 列的示例,最后两列分别为range_scan_count
和singleton_lookup_count
):
╔════════╦═════════════════╦════╦═══╦═══╦═══╦═══╦════════╦══════════╗
║ datetb ║ idx_datetb_col ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 205740 ║ 3486408 ║
║ datetb ║ idx_datetb_col ║ 2 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 1079649 ║
║ datetb ║ idx_datetb_col ║ 3 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 1174547 ║
║ datetb ║ idx_datetb_col ║ 4 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 2952991 ║
║ datetb ║ idx_datetb_col ║ 5 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 3974886 ║
║ datetb ║ idx_datetb_col ║ 6 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 2931450 ║
║ datetb ║ idx_datetb_col ║ 7 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 3316960 ║
║ datetb ║ idx_datetb_col ║ 8 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 3393439 ║
║ datetb ║ idx_datetb_col ║ 9 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 3735495 ║
║ datetb ║ idx_datetb_col ║ 10 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 4803804 ║
║ datetb ║ idx_datetb_col ║ 11 ║ 0 ║ 0 ║ 0 ║ 0 ║ 29617 ║ 7655091 ║
║ datetb ║ idx_datetb_col ║ 12 ║ 1 ║ 0 ║ 0 ║ 0 ║ 174326 ║ 47377226 ║
╚════════╩═════════════════╩════╩═══╩═══╩═══╩═══╩════════╩══════════╝
我看到了一些不同的可能性,但我需要一些关于如何思考这个的方向(当然我在“可能”中表达这个因为我知道“这取决于”,但我也在寻找概念理解):
- 所有分区的相似值
range_scan_count
可能表明我们没有得到很好的分区消除,因为我们扫描所有分区的次数大致相同。 - 所有分区的不同值
singleton_lookup_count
伴随着明显较低的值range_scan_count
可能表明分区消除频率很高,因为我们扫描的次数少于我们正在寻找的次数。 - ?
到目前为止,这些是我的想法。我希望有人权衡我如何使用这个或另一组信息来确定哪些表最有可能从完全放弃分区以支持索引中受益。
编辑
这是一个剪辑的 DDL:
CREATE TABLE [dbo].[date_table](
[date_id] [int] NOT NULL,
[calendar_date] [datetime] NULL,
[valdate] [datetime] NULL,
CONSTRAINT [PK_datedb] PRIMARY KEY CLUSTERED
(
[date_id] ASC
) ON [partschm]([date_id]);
CREATE UNIQUE NONCLUSTERED INDEX [idx_datetb_col] ON [dbo].[date_table]
(
[calendar_date] DESC,
[date_id] ASC
) ON [partschm]([date_id])
GO
我不会查看索引利用率,而是查看计划缓存以找到具有最高逻辑读取量的查询。通常,当我处理分区时,我发现只有少数查询在主导读取——比如服务器总体读取的 50-80%。检查这些查询以查看它们是否成功地进行了分区消除。
如果他们没有进行分区消除,但您认为他们应该(根据您的分区方案),则与查询编写者一起进行分区消除。
如果他们没有消除分区,而且他们不能(因为查询的编写方式或分区的设计方式),那么是时候开始提出棘手的问题了。
如果最大的逻辑读取查询与您的分区表没有任何关系,那么继续关注那些其他查询。