39 votes

MS SQL Server - Quand un CURSEUR est-il bon ?

Souvent, lorsque j'ai écrit des procédures stockées, etc. j'utilise d'abord un CURSEUR et je trouve ensuite un problème de performance avec ma procédure.

Tout ce que j'ai lu dit que les CURSEURS sont horribles, qu'ils causent des verrouillages inutiles, etc. et les tests de performance prouvent la même chose.

Ma question est la suivante : quand utilisez-vous un CURSEUR et dans quelles situations est-il utile ou bon ?

S'il n'y a aucune utilité, pourquoi faire une structure/un type de contrôle aussi mauvais pour SQL ?

37voto

HLGEM Points 54641

Normalement, ils sont à éviter, mais la fonction est là pour une raison et il y a des moments où il faut les utiliser. Je dirais que 90+% des curseurs que j'ai vus ne sont pas nécessaires. Si vous les utilisez pour des opérations CRUD, elles peuvent presque toujours être refaites en utilisant des ensembles. J'ai souvent vu des gens utiliser des curseurs pour cela parce qu'ils ne savaient pas comment utiliser les jointures dans une mise à jour ou une suppression ou qu'ils pouvaient utiliser un select statment au lieu d'une clause values dans une insertion. Une autre utilisation inutile est celle des personnes qui pensent avoir besoin d'eux pour un traitement légèrement plus complexe qui, en fait, pourrait facilement être traité avec une instruction case.

Les curseurs sont parfois plus rapides pour calculer quelque chose comme un total courant.

Les curseurs sont également pratiques pour les exécutions multiples d'une procédure stockée qui est configurée pour traiter une seule valeur d'entrée à la fois. Je n'utilise pas cette fonctionnalité pour exécuter des procédures stockées par l'utilisateur (à moins que je ne sache que je vais frapper un très petit ensemble de données) mais elle est très pratique pour les administrateurs de bases de données lorsqu'ils ont besoin d'exécuter des procédures système sur plusieurs tables.

Si vous créez des courriels en SQl (ce n'est pas le meilleur endroit pour le faire, mais c'est là qu'on le fait dans certains systèmes) et que vous ne voulez pas que tous les destinataires du courriel voient les autres personnes de la liste ou que vous voulez personnaliser chaque courriel avec des informations sur le destinataire, les curseurs sont la solution.

Des curseurs ou des boucles peuvent également être utilisés pour traiter des lots d'enregistrements si l'insertion/mise à jour/suppression complète basée sur un ensemble prend trop de temps et bloque les tables. Il s'agit d'une sorte d'hybride entre les curseurs et la solution basée sur les ensembles et c'est souvent la meilleure solution pour les changements importants sur les systèmes de production.

8voto

keithwarren7 Points 6672

Un jour, j'ai demandé à un membre de l'équipe SQL Server : "Si vous pouviez ajouter une fonction qui améliorerait le produit pour tout le monde, quelle serait-elle ?

Sa réponse a été "Ajouter ? Huh, j'en enlèverais un. Si vous vous débarrassez des curseurs, vous obligerez les programmeurs du monde entier à commencer à penser aux choses d'une manière basée sur les SETs et ce sera la plus grande augmentation mondiale des performances des bases de données que vous ne verrez jamais".

Pour ma part, j'ai tendance à voir un modèle, il semble qu'il y ait beaucoup de codeurs procéduraux qui utilisent des curseurs parce qu'ils ont besoin de pouvoir faire une opération un élément à la fois et manquent le bon vieux concept de boucle WHILE. La même idée de base sans la surcharge du curseur. Ce n'est toujours pas aussi rapide/efficace que quelque chose basé sur le SET, mais dans 90% des cas, quand quelqu'un dit "Je ne peux pas faire ça en utilisant le SET, je dois utiliser des curseurs", je peux lui faire faire avec une boucle while.

1voto

RBarryYoung Points 23349

Voici un article rédigé par un homme aux opinions bien tranchées, qui explique pourquoi il ne faut pas utiliser les curseurs et comment ils ont été créés : Il doit y avoir 15 façons de perdre ses curseurs .

1voto

womp Points 71924

Le manuel de préparation MCTS pour SQL Server 2008 que j'étudie recommande d'utiliser du code CLR externe partout où un CURSOR serait nécessaire dans T-SQL, surtout depuis que SQL Server 2008 prend en charge les fonctions d'agrégation personnalisées.

Il y a 5 ans, je les utilisais pour des fonctions de reporting étendues, mais je ne pense pas que je pourrais trouver un bon cas d'utilisation pour eux maintenant. Les agrégats et les fonctions CLR fonctionnent de manière similaire aux fonctions d'agrégation intégrées.

1voto

Iconiu Points 11

OMG, comment ai-je pu oublier le Group By ? J'ai pris la requête basée sur le curseur que vous voyez ci-dessous et je l'ai remplacée par celle qui suit. Maintenant j'obtiens un seul ensemble de résultats et il n'y a pas de problème avec l'utilisation de sqlsrv_next_result() en php.

DECLARE @thisday datetime;

DECLARE daycursor CURSOR FOR
SELECT DISTINCT DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as thisday
FROM computerusedata

OPEN daycursor;
FETCH NEXT FROM daycursor
INTO @thisday;
WHILE @@FETCH_STATUS = 0
    BEGIN
    select distinct left(ComputerName,5) as CompGroup,DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day
    FROM computerusedata
    where DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) = @thisday
    order by CompGroup;
    FETCH NEXT FROM daycursor;
    END;
CLOSE daycursor;
DEALLOCATE daycursor;";

select DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day,left(ComputerName,5) as CompGroup
from ComputerUseData
group by DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)),left(ComputerName,5)
order by day,CompGroup

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X