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?

dba.stackexchange https://dba.stackexchange.com/questions/30210

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

offset-fetch.png

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
scroll top