Eu tenho uma tabela do SQL Server 2008 R2 cuja estrutura de esquema é a seguinte:
CREATE TABLE [dbo].[CDSIM_BE]
(
[ID] [bigint] NOT NULL,
[EquipmentID] [varchar](50) NOT NULL,
[SerialNumber] [varchar](50) NULL,
[PyrID] [varchar](50) NULL,
[MeasMode] [varchar](50) NULL,
[ReadTime] [datetime] NOT NULL,
[SubID] [varchar](15) NULL,
[ProbePosition] [float] NULL,
[DataPoint] [int] NULL,
CONSTRAINT [PK_CDSIM_BE]
PRIMARY KEY CLUSTERED ([ID] ASC, [EquipmentID] ASC, [ReadTime] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])
) ON [MonthlyArchiveScheme9]([ReadTime])
CREATE NONCLUSTERED INDEX [idx_CDSIM_BE__SubID_ProbePosition]
ON [dbo].[CDSIM_BE] ([SubID] ASC, [ProbePosition] ASC)
INCLUDE ([EquipmentID], [ReadTime], [BECorr])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])
CREATE NONCLUSTERED INDEX [IX_CDSIM_BE_ProbePosition]
ON [dbo].[CDSIM_BE] ([ProbePosition] ASC)
INCLUDE ([SerialNumber], [SubID])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])
CREATE NONCLUSTERED INDEX [IX_CSDIM_Readtime]
ON [dbo].[CDSIM_BE]([ReadTime] ASC)
INCLUDE ([EquipmentID])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])
E estou executando esta consulta simples:
Select Max(Id)
From dbo.CDSIM_BE
Existem ~ 2,5B linhas na tabela.
O plano de consulta mostra uma verificação de índice sendo feita no IX_CdSIM_BE_ProbePosition
índice. Eu estou querendo saber por que o SQL Server simplesmente não usaria o índice clusterizado (e primário) e imediatamente foi para a última linha da tabela e recuperou o valor de ID, pois esse deve ser o máximo.
sql-server
sql-server-2008-r2
query-performance
query-optimization
execution-plan
Randy Minder
fonte
fonte
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
portanto, não foi possível usar o PK como você descreve. Seria necessário encontrar oMax(Id)
para cada partição e, em seguida, encontrar o máximo deles. É possível reescrever a consulta para obter esse plano um como aludido aqui, porém dba.stackexchange.com/a/99418/3690Respostas:
O índice em cluster é particionado,
ReadTime
portanto, não foi possível usar o PK como você descreve. Seria necessário encontrar oMax(Id)
para cada partição e, em seguida, encontrar o máximo deles. Ele é possível reescrever a consulta para obter esse plano um porém.Usando um exemplo baseado no artigo aqui, uma possível reescrita pode ser
Para processar cada partição por vez.
Observe que o plano ainda possui uma varredura (com um predicado de busca para selecionar a partição), mas essa não é uma varredura completa da partição.
A varredura está na ordem do índice com a direção "BACKWARD". O
TOP
iterador pode parar de solicitar linhas da varredura após o recebimento da primeira.fonte