Tengo una tabla de SQL Server 2008 R2 cuya estructura de esquema se ve de la siguiente manera:
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])
Y estoy ejecutando esta simple consulta:
Select Max(Id)
From dbo.CDSIM_BE
Hay ~ 2.5B filas en la tabla.
El plan de consulta muestra una exploración de índice que se realiza en el IX_CdSIM_BE_ProbePosition
índice. Me pregunto por qué SQL Server simplemente no usaría el índice agrupado (y primario) e inmediatamente iría a la última fila de la tabla y recuperaría el valor Id, ya que ese debe ser el máximo.
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
para que no pueda usar la PK como usted describe. Tendría que encontrar elMax(Id)
para cada partición y luego encontrar el máximo de esos. Es posible reescribir la consulta para obtener un plan como el mencionado aquí, aunque dba.stackexchange.com/a/99418/3690Respuestas:
El índice agrupado está particionado
ReadTime
para que no pueda usar la PK como usted describe. Tendría que encontrar elMax(Id)
para cada partición y luego encontrar el máximo de esos. Sin embargo, es posible reescribir la consulta para obtener dicho plan.Usando un ejemplo basado en el artículo aquí, una posible reescritura podría ser
Para procesar cada partición a su vez.
Tenga en cuenta que el plan todavía tiene una exploración (con un predicado de búsqueda para seleccionar la partición) pero esta no es una exploración completa de la partición.
La exploración está en orden de índice con la dirección "HACIA ATRÁS". El
TOP
iterador puede dejar de solicitar filas del escaneo después de recibir el primero.fuente