web-dev-qa-db-fra.com

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

Plusieurs fois, lorsque j'ai écrit des procédures stockées, etc. J'utilise un curseur au début et ensuite, trouvez une question de performance avec ma procédure.

Tout ce que je lis dit que les curseurs sont affreux, causent un verrouillage inutile, etc. et des tests de performance prouvent la même chose.

Ma question est quand utilisez-vous un curseur et dans quelles situations sont-elles utiles ou bonnes?

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

39
jonathanpeppers

J'ai demandé à un gars sur l'équipe SQL Server une fois, si vous pouviez ajouter une fonctionnalité qui rendrait le produit mieux pour tout le monde, que serait-il?

Sa réponse était 'Ajouter? Hein, je sortirais un loin. Si vous vous débarrassez des curseurs, vous forcez les programmeurs du monde entier pour commencer à penser à des choses de manière définie et qui sera la plus grande augmentation mondiale de la performance de la DB que vous verrez jamais. '

Pour ma part, j'ai tendance à voir un modèle, il semble y avoir beaucoup de codeurs de procédure qui utilisent des curseurs car ils doivent pouvoir effectuer une opération un élément à la fois et manquer la vieille mode tandis que le concept de boucle. Même idée de base sans le curseur au-dessus de la tête. Encore pas aussi vite/efficace que quelque chose en jeu, mais 90% du temps où quelqu'un affirme que je ne peux pas faire cela, je dois utiliser des curseurs, je peux les amener à le faire avec une boucle de temps.

8
keithwarren7

Voici un article d'un autre membre d'une opinion, qui donne un raisonnement à ne pas utiliser de curseurs et de certaines réponses sur la manière dont ils sont venus être: Il doit y avoir 15 façons de perdre vos curseurs .

1
RBarryYoung

Seul le temps que je vais les utiliser, c'est quand tout ce qui est fait à l'intérieur du curseur doit absolument faire un élément à la fois et où tout ce qui est fait à l'intérieur du curseur prend tant de temps que les frais généraux du curseur tombent dans l'insignifiance.

Par exemple, les sauvegardes de base de données, les contrôles d'intégrité, les reconstructions de l'index. En bref, les tâches administratives.

1
GilaMonster

OMG, comment ai-je oublié le groupe? J'ai pris la requête basée sur le curseur que vous voyez ci-dessous et l'a remplacée par celle-ci une après. Maintenant, je reçois un ensemble de résultats unique, donc il n'y a pas de problèmes avec SQLSRV_NEXT_RESULT () dans 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
1
Iconiu

Le manuel de préparation MCTS pour SQL Server 2008 que j'étudie recommande d'utiliser un code CLR externe n'importe où qu'un curseur serait requis dans T-SQL, en particulier maintenant que SQL Server 2008 prend en charge les fonctions d'agrégat personnalisées.

Il y a 5 ans, j'ai travaillé avec eux pour des caractéristiques de reporting approfondies, mais je ne pense pas pouvoir trouver un cas de bon usage pour eux maintenant. Les agrégats et fonctions CLR fonctionnent de la même manière aux fonctions globales intégrées.

1
womp

Je n'utilise généralement pas des curseurs, mais quand je le fais, il doit s'agir d'une requête "unique" que je cours localement ou un travail quotidien. Vous souhaitez vous abstenir d'avoir un code de production appeler un curseur qui serait invoqué fréquemment comme en réponse à une demande Web.

0
Matt Wrock

Les curseurs sont utiles lorsque vous devez faire quelque chose que vous ne pouvez pas faire avec une opération définie, ou 2) Il n'a pas de sens de faire le même travail en faisant des appels itératifs de la couche d'application. Ou parfois, vous avez une procédure qui doit rester sur le calque de base de données et vous ne pouvez tout simplement pas rompre à la couche d'application à mi-parcours à itérer sur un ensemble de résultats.

Une recommandation que je ferais cependant, c'est que les gens utilisent des variables de curseur plutôt que des curseurs normaux, car vous évitez les problèmes d'allocation de curseur/distribution qui entourent des curseurs normaux. Avec un curseur normal, si vous ne les interdisez pas, ils persistent, ce qui peut être une source de fuites de mémoire. Pas ainsi avec des curseurs à base de variables (c'est-à-dire le curseur @cursor @cursor).

Le résultat final est, évitez-les si vous pouvez éventuellement, et si vous ne pouvez pas, utilisez-les peu et judicieusement.

0
Dane

Vous utilisez du curseur pour la reconstruction ou la réorganisation des index de table individuellement
Sauf s'il y a un moyen d'exécuter alter index ... en tant qu'observation basée sur un ensemble.

0
dance2die