Ich habe eine SQL Server 2008 R2-Tabelle, deren Schemastruktur wie folgt aussieht:
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])
Und ich führe diese einfache Abfrage aus:
Select Max(Id)
From dbo.CDSIM_BE
Die Tabelle enthält ~ 2,5B Zeilen.
Der Abfrageplan zeigt einen Index-Scan, der für den IX_CdSIM_BE_ProbePosition
Index durchgeführt wird. Ich frage mich, warum SQL Server den Clustered- (und Primär-) Index einfach nicht verwenden und sofort zur letzten Zeile in der Tabelle gehen und den ID-Wert abrufen würde, da dies das Maximum sein muss.
sql-server
sql-server-2008-r2
query-performance
query-optimization
execution-plan
Randy Minder
quelle
quelle
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
sodass die von Ihnen beschriebene PK nicht verwendet werden kann. Es müsste dasMax(Id)
für jede Partition finden und dann das Maximum von diesen finden. Es ist möglich, die Abfrage neu zu schreiben, um einen Plan zu erhalten, auf den hier hingewiesen wird, obwohl dba.stackexchange.com/a/99418/3690Antworten:
Der Clustered-Index ist partitioniert,
ReadTime
sodass die von Ihnen beschriebene PK nicht verwendet werden kann. Es müsste dasMax(Id)
für jede Partition finden und dann das Maximum von diesen finden. Es ist jedoch möglich, die Abfrage neu zu schreiben, um einen solchen Plan zu erhalten.Anhand eines Beispiels, das auf dem Artikel hier basiert, könnte ein mögliches Umschreiben sein
Jede Partition nacheinander verarbeiten.
Beachten Sie, dass der Plan noch einen Scan enthält (mit einem Suchprädikat zur Auswahl der Partition), dies jedoch kein vollständiger Scan der Partition ist.
Der Scan erfolgt in Indexreihenfolge mit der Richtung "BACKWARD". Der
TOP
Iterator kann aufhören, Zeilen vom Scan anzufordern, nachdem die erste empfangen wurde.quelle