Mam tabelę SQL Server 2008 R2, której struktura schematu wygląda następująco:
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])
I wykonuję to proste zapytanie:
Select Max(Id)
From dbo.CDSIM_BE
Tabela zawiera ~ 2,5B wierszy.
Plan zapytań pokazuje skanowanie indeksu wykonywane na IX_CdSIM_BE_ProbePosition
indeksie. Zastanawiam się, dlaczego SQL Server po prostu nie używałby indeksu klastrowanego (i podstawowego) i od razu przejdzie do ostatniego wiersza w tabeli i pobierze wartość Id, ponieważ musi to być wartość maksymalna.
sql-server
sql-server-2008-r2
query-performance
query-optimization
execution-plan
Randy Minder
źródło
źródło
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
więc nie można użyć PK, jak opisano. Musi znaleźćMax(Id)
dla każdej partycji, a następnie znaleźć ich maksimum. Możliwe jest przepisanie zapytania, aby uzyskać plan, o którym tu mowa,Odpowiedzi:
Indeks klastrowany jest podzielony na partycje,
ReadTime
więc nie można użyć PK, jak opisano. Musi znaleźćMax(Id)
dla każdej partycji, a następnie znaleźć ich maksimum. Możliwe jest jednak przepisanie zapytania, aby uzyskać taki plan.Korzystając z przykładu opartego na tym artykule, możliwe jest przepisanie
Aby kolejno przetwarzać każdą partycję.
Zauważ, że plan nadal ma skan (z predykatem wyszukiwania, aby wybrać partycję), ale nie jest to pełny skan partycji.
Skanowanie odbywa się w kolejności indeksu z kierunkiem „BACKWARD”.
TOP
Iterator może zatrzymać zainteresowanie wiersze ze skanowania po otrzymaniu pierwszego.źródło