Versão: SQL Server 2008 R2 Enterprise Edtn. (10.50.4000)
Na tentativa de avaliar nossa estratégia de particionamento, escrevi esta consulta para obter os métodos de acesso em relação aos índices nas partições (no sentido mais amplo do termo, embora esteja eliminando heaps). Ao restringir meu foco às tabelas particionadas, acredito que preciso estar olhando, range_scan_count
mas singleton_lookup_count
estou tendo dificuldade em conceituar.
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 ;
Saída relevante (dada a lacuna na formatação de tabelas do SO, esta é uma amostra das primeiras 9 colunas da consulta acima com as duas últimas colunas sendo range_scan_count
e singleton_lookup_count
, respectivamente):
╔════════╦═════════════════╦════╦═══╦═══╦═══╦═══╦════════╦══════════╗
║ 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 ║
╚════════╩═════════════════╩════╩═══╩═══╩═══╩═══╩════════╩══════════╝
Vejo algumas possibilidades diferentes, mas preciso de alguma orientação sobre como pensar sobre isso (claro que estou colocando isso em " pode " porque sei que "depende", mas também estou procurando compreensão conceitual):
- Valores semelhantes para todas as partições
range_scan_count
podem indicar que não estamos obtendo uma boa eliminação de partição porque estamos verificando todas as partições aproximadamente o mesmo número de vezes. - Valores variados para todas as partições de
singleton_lookup_count
acompanhados de valores significativamente mais baixos pararange_scan_count
podem indicar uma boa eliminação frequente de partições porque estamos verificando menos do que procuramos. - ?
Esses são meus pensamentos até agora. Eu esperava que alguém avaliasse como eu poderia usar isso, ou outro conjunto de informações, para determinar quais tabelas provavelmente se beneficiariam com a eliminação do particionamento em favor de índices.
EDITAR
Aqui está um DDL recortado:
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
Em vez de olhar para a utilização do índice, eu olharia para o cache do plano para encontrar suas consultas com as maiores quantidades de leituras lógicas. Normalmente, quando estou lidando com particionamento, encontro apenas um punhado de consultas que dominam as leituras - como 50-80% das leituras dos servidores em geral. Verifique essas consultas para ver se estão fazendo a eliminação de partições com sucesso.
Se eles não estiverem fazendo a eliminação da partição, mas você acha que deveriam (com base no seu esquema de partição), trabalhe com os gravadores de consulta para obter a eliminação da partição.
Se eles não estão eliminando partições e não podem (devido à forma como a consulta é escrita ou a partição é projetada), então é hora de começar a fazer perguntas difíceis.
Se as maiores consultas de leitura lógica não tiverem nada a ver com sua tabela particionada, siga em frente e concentre-se nessas outras consultas.