У меня есть таблица SQL Server 2008 R2, структура схемы выглядит следующим образом:
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])
И я выполняю этот простой запрос:
Select Max(Id)
From dbo.CDSIM_BE
В таблице ~ 2,5В строк.
План запроса показывает сканирование индекса, выполняемое для IX_CdSIM_BE_ProbePosition
индекса. Мне интересно, почему SQL Server просто не будет использовать кластерный (и основной) индекс и сразу же перейдет к последней строке таблицы и получит значение Id, поскольку оно должно быть максимальным.
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
поэтому он не может использовать PK, как вы описываете. Необходимо найтиMax(Id)
для каждого раздела, а затем найти максимум из них. Можно переписать запрос, чтобы получить такой план, как указаноОтветы:
Кластерный индекс разделен на части,
ReadTime
поэтому он не может использовать PK, как вы описываете. Необходимо найтиMax(Id)
для каждого раздела, а затем найти максимум из них. Это есть возможность переписать запрос , чтобы получить такой план , однако.Используя пример, основанный на статье здесь, возможное переписывание может быть
Обрабатывать каждый раздел по очереди.
Обратите внимание, что план все еще имеет сканирование (с предикатом поиска для выбора раздела), но это не полное сканирование раздела.
Сканирование выполняется в индексном порядке с направлением «НАЗАД».
TOP
Итератора может остановить запрос строки из сканирования после того, как первый из них получен.источник