J'ai une table SQL Server 2008 R2 dont la structure de schéma ressemble à ceci:
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])
Et j'exécute cette simple requête:
Select Max(Id)
From dbo.CDSIM_BE
Il y a environ 2,5 milliards de lignes dans le tableau.
Le plan de requête montre une analyse d'index en cours sur l' IX_CdSIM_BE_ProbePosition
index. Je me demande pourquoi SQL Server n'utiliserait tout simplement pas l'index cluster (et principal) et irait immédiatement à la dernière ligne de la table et récupérerait la valeur Id, car cela devait être le maximum.
sql-server
sql-server-2008-r2
query-performance
query-optimization
execution-plan
Randy Minder
la source
la source
select top 1 Id from dbo.CDSIM_BE order by Id descending;
ReadTime
sorte qu'il ne pouvait pas utiliser le PK comme vous le décrivez. Il faudrait trouver leMax(Id)
pour chaque partition, puis trouver le maximum de ceux-ci. Il est possible de réécrire la requête pour obtenir un tel plan comme mentionné ici via dba.stackexchange.com/a/99418/3690Réponses:
L'index cluster est partitionné de
ReadTime
sorte qu'il ne pouvait pas utiliser le PK comme vous le décrivez. Il faudrait trouver leMax(Id)
pour chaque partition, puis trouver le maximum de ceux-ci. Il est cependant possible de réécrire la requête pour obtenir un tel plan.En utilisant un exemple basé sur l'article ici, une réécriture possible pourrait être
Pour traiter chaque partition tour à tour.
Notez que le plan a toujours un scan (avec un prédicat de recherche pour sélectionner la partition) mais ce n'est pas un scan complet de la partition.
Le balayage est dans l'ordre d'index avec la direction "BACKWARD". L'
TOP
itérateur peut arrêter de demander des lignes à l'analyse une fois la première reçue.la source