web-dev-qa-db-fra.com

Pourquoi choisir une requête supérieure et une table temporaire au lieu d'un curseur pour une boucle?

Lorsqu'il s'agit de boucler sur un grand ensemble de données dans T-SQL, la majorité des exemples que je vois sur Internet utilisent un motif comme celui-ci:

declare @someVariable int
declare @remainingRows int

select someColumn from someTables into #someTempTable

select @remainingRows = count(*) from #someTempTable
while @remainingRows > 0 begin

    select top 1 @someVariable = someColumn from #someTempTable

    -- Do stuff

    delete top 1 from #someTempTable

    select @remainingRows = count(*) from #someTempTable
end

Cela semble être beaucoup plus commun que les échantillons d'utilisation de curseurs comme celui-ci:

declare @someVariable int

select someColumn from someTables into #someTempTable

declare @someCursor cursor for select someColumn from #someTempTable
open @someCursor
fetch next @someVariable from @someCursor

while @@fetch_status = 0 begin

    -- Do stuff

    fetch next @someVariable from @someCursor
end

close @someCursor

J'entends parfois mentionner des raisons de performance, mais pour moi, c'est contre-intuitif; Un curseur en lecture en lecture-seul en avant ne serait-il pas un ensemble de données sur un ensemble de données, soit-il beaucoup plus efficace que de manière constante interrogée et à la mise à jour d'une table temporaire? Je comprends que s'il s'agissait d'un curseur itérant sur une table avec les mauvaises options que la table pourrait être verrouillée pour des mises à jour, mais un curseur sur une table temporaire non partagée n'aurait-il pas ce problème, n'est-ce pas?

Question bonus; Si les curseurs sont corrects, un curseur sur une requête régulière utilise une isolation d'instantané soit en sécurité afin que je puisse éviter la contrariété de créer manuellement une table temporaire, c'est-à-dire

DECLARE @someCursor CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR 
SELECT something
FROM tables
5
Jacob

Non, une boucle n'est pas nécessairement plus rapide qu'un curseur, bien que certaines personnes soient plus à l'aise avec eux. J'ai traversé la phase d'écriture de la boucle moi-même à la fois. Les curseurs arrivent également dans plusieurs arômes, alors choisir le bon type de curseur est un détail important.

Votre question est probablement répondue par Aaron Bertrand (à partir de 2012), puisqu'il a exécuté plusieurs tests comparatifs, à l'adresse suivante:

En bref, il a constaté que le curseur approprié a été significativement plus rapide que plusieurs constructions de boucle.

Lecture à travers ses comparaisons devrait vous aider à vous sentir à l'aise avec des curseurs.

Mais seulement quand ils sont nécessaires.

9
RLF