Pourquoi y a-t-il des différences de plan d'exécution entre le décalage… Fetch et le schéma ROW_NUMBER à l'ancienne?
-
31-10-2019 - |
Question
Le nouveau OFFSET ... FETCH
Le modèle introduit avec SQL Server 2012 offre une pagination simple et plus rapide. Pourquoi y a-t-il des différences étant donné que les deux formes sont sémantiquement identiques et très courantes?
On supposerait que l'optimiseur reconnaît les deux et les optimise (trivialement) au maximum.
Voici un cas très simple où OFFSET ... FETCH
est ~ 2x plus rapide selon l'estimation des coûts.
SELECT * INTO #objects FROM sys.objects
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY object_id) r
FROM #objects
) x
WHERE r >= 30 AND r < (30 + 10)
ORDER BY object_id
SELECT *
FROM #objects
ORDER BY object_id
OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY
On peut varier ce cas de test en créant un CI sur object_id
ou l'ajout de filtres mais il est impossible de supprimer toutes les différences de plan. OFFSET ... FETCH
est toujours plus rapide car il fonctionne moins au moment de l'exécution.
Pas de solution correcte
Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange