Les avantages et les inconvénients de l'utilisation d'un curseur (SQL server)
J'ai posé une question ici À l'aide du curseur dans OLTP bases de données (SQL server)
où les gens ont répondu en disant curseurs ne doit jamais être utilisé.
Je sens les curseurs sont des outils très puissants qui sont destinés à être utilisés (je ne pense pas que Microsoft prend en charge les curseurs pour les mauvais développeurs).Supposons que vous disposez d'une table où la valeur d'une colonne dans une ligne dépend de la valeur de la même colonne de la rangée précédente. Si c'est une fois de retour en fin de processus, vous ne pensez pas à l'aide d'un curseur serait un choix acceptable?
Sur le dessus de ma tête, je ne peux penser à un couple de scénarios où je me sens il devrait y avoir aucune honte à l'aide de curseurs. S'il vous plaît laissez-moi savoir si vous les gars se sentent autrement.
1>Une fois de retour en fin de processus pour nettoyer les données de mauvaise qualité qui termine l'exécution dans un délai de quelques minutes.
2>Lot processus qui s'exécutent une fois dans une longue période de temps (quelque chose comme une fois par an).
Si dans les scénarios ci-dessus, il n'est pas visible de la souche sur les autres processus, ne serait-il pas déraisonnable de passer des heures supplémentaires à l'écriture de code pour éviter les curseurs? En d'autres termes, dans certains cas, le développeur du temps est plus important que la performance d'un processus qui n'a presque aucune incidence sur quoi que ce soit d'autre.
À mon avis, ce serait certains scénarios où vous devriez sérieusement essayez d'éviter l'utilisation d'un curseur.
1>Une procédure stockée appelée à partir d'un site web qui peut être appelé très souvent.
2>UN travail SQL pour exécuter plusieurs fois par jour et de consommer beaucoup de ressources.
Je pense que c'est très superficiel pour faire une déclaration générale comme "les curseurs ne devraient jamais être utilisés" sans analyser la tâche à portée de main et fait de pesée contre les solutions de rechange.
S'il vous plaît laissez-moi savoir vos pensées.
"Une procédure stockée appelée à partir d'un site web" est trop vague. Si un curseur est le plus raisonnable pour résoudre un problème, et la procédure doit être appelée à partir d'une page web...
OriginalL'auteur developer747 | 2012-02-16
Vous devez vous connecter pour publier un commentaire.
Il y a plusieurs scénarios où les curseurs effectuer réellement mieux que le jeu de base équivalents. Totaux en cours d'exécution est celui qui me vient à l'esprit - look pour Itzik de mots (et ignorer tout qui impliquent SQL Server 2012, qui ajoute de nouvelles fonctions de fenêtrage qui donnent les curseurs d'une course pour leur argent dans cette situation).
L'un des grands problèmes que les gens ont avec les curseurs, c'est qu'ils exécutent plus lentement, ils utilisent le stockage temporaire, etc. C'est en partie parce que la syntaxe par défaut est un curseur global avec toutes sortes de l'inefficacité des options par défaut. La prochaine fois que vous êtes en train de faire quelque chose avec un curseur qui n'a pas besoin de faire des choses comme
UPDATE...WHERE CURRENT OF
(que j'ai réussi à éviter de toute ma carrière), de lui donner un traitement équitable par la comparaison de ces deux options de syntaxe:En fait la première version représente un bug dans le sans-papiers procédure stockée sp_MSforeachdb qui fait sauter des bases de données si l'état de toutes les modifications de base de données lors de l'exécution. J'ai par la suite écrit ma propre version de la procédure stockée (voir ici et ici) qui fixe le bogue (en utilisant simplement la dernière version de la syntaxe ci-dessus) et ajouté plusieurs paramètres pour contrôler les bases de données qui serait choisi.
Beaucoup de gens pensent qu'une méthode n'est pas un curseur parce qu'il ne dit pas
DECLARE CURSOR
. J'ai vu ceux qui prétendent qu'une boucle while est plus rapide qu'un curseur (qui, je l'espère, j'ai dissipé ici) ou que l'utilisation deFOR XML PATH
pour effectuer groupe de concaténation n'est pas l'exécution d'une cachée opération de curseur. En regardant le plan, dans beaucoup de cas va vous montrer la vérité.Dans beaucoup de cas, les curseurs sont utilisés lorsque la base de jeu est plus approprié. Mais il y a beaucoup d'utilisation valide les cas où une base de jeu équivalent est beaucoup plus compliqué à écrire, pour que l'optimiseur pour générer un plan pour, à la fois, ou pas possible (par exemple, les tâches de maintenance où vous êtes en boucle à travers des tableaux pour la mise à jour des statistiques, de l'appel d'une procédure stockée pour chaque valeur d'un résultat, etc.). Le même est vrai pour un grand nombre de multi-requêtes de table où le plan est trop monstrueux pour l'optimiseur de la poignée. Dans ces cas, il peut être préférable de vidage de certains des résultats intermédiaires dans une structure temporaire en premier. Il en va de même pour certains, basés sur les équivalents pour les curseurs (comme la course totaux). J'ai également écrit sur l'autre voie, où les gens presque toujours penser instinctivement à utiliser une boucle while /curseur et il y a intelligents, basés sur les solutions de rechange qui sont beaucoup mieux.
Mise à JOUR 2013-07-25
Voulais juste ajouter quelques autres billets de blog que j'ai écrits sur les curseurs, les options dont vous devriez utiliser si vous ne à les utiliser, et à l'aide de jeu basé sur des requêtes au lieu de boucles pour générer des ensembles:
Meilleur Approches pour des cumuls - mise à Jour pour SQL Server 2012
Quelles sont les conséquences de différentes options de curseur?
Générer un Ensemble ou d'une Séquence Sans Boucles: [Partie 1] [Partie 2] [Partie 3]
OriginalL'auteur Aaron Bertrand
Le problème avec les curseurs dans SQL Server, c'est que le moteur est mis en fonction en interne, contrairement à d'autres SGBD est comme Oracle qui sont à la base de curseur à l'interne. Cela signifie que lorsque vous créez un curseur dans SQL Server, le stockage temporaire doit être créé et la base de jeu de jeu de résultats doit être copié sur le temporaire curseur de stockage. Vous pouvez voir pourquoi ce serait cher dès le départ, pour ne pas mentionner toute la ligne-par-ligne de traitement que vous pourriez faire sur le dessus du curseur lui-même. La ligne de fond est que le traitement à base de jeu est plus efficace, et souvent votre curseur de base de fonctionnement peut être mieux fait à l'aide d'un CTE ou de la table temporaire.
Cela étant dit, il ya des cas où un curseur est probablement acceptable, comme vous l'avez dit pour les opérations uniques. L'utilisation la plus commune est, je pense, dans un plan de maintenance où l'on peut itérer sur toutes les bases de données sur un serveur de l'exécution de diverses tâches de maintenance. Aussi longtemps que vous limitez votre utilisation et de ne pas la conception de l'ensemble des applications autour de RBAR (ligne-par-atroce-ligne) de traitement, vous devriez être bien.
OriginalL'auteur Pam Lahoud
En général, les curseurs sont une mauvaise chose. Toutefois, dans certains cas, il est plus pratique d'utiliser un curseur et dans certains, il est même plus rapide à utiliser. Un bon exemple est un curseur dans une table contact de l'envoi des emails en fonction de certains critères. (Ne pas ouvrir la question de savoir si l'envoi d'un e-mail à partir de votre SGBD est une bonne idée, disons simplement supposer qu'il est pour le problème à la main.) Il n'existe aucun moyen d'écrire à base de jeu. Vous pouvez utiliser quelques astuces pour venir avec un jeu basé sur la solution pour générer le SQL dynamique, mais une véritable base de jeu solution n'existe pas.
Cependant, un calcul impliquant la rangée précédente peut être fait à l'aide d'une auto-jointure. C'est généralement encore plus rapide qu'un curseur.
Dans tous les cas, vous avez besoin pour équilibrer l'effort impliqué dans le développement d'une solution plus rapide. Si personne ne se soucie, si vous le processus s'exécute en 1 minute ou une heure, l'utilisation que fait le travail plus rapide. Si vous êtes en boucle par le biais d'un ensemble de données qui se développe au fil du temps comme un [commandes] de la table, essayez de rester à l'écart à partir d'un curseur, si possible. Si vous n'êtes pas sûr, faire un test de performance en comparant un curseur de base avec une solution basée sur plusieurs significativement différentes tailles de données.
OriginalL'auteur Sebastian Meine
Ils sont nécessaires pour des choses comme le SQL dynamique de pivot, mais vous devriez essayer et d'éviter de les utiliser chaque fois que possible.
OriginalL'auteur Vince Pergolizzi
J'avais toujours détesté les curseurs en raison de la lenteur de leurs performances. Cependant, j'ai constaté que je n'arrivais pas à bien comprendre les différents types de curseurs et que, dans certains cas, les curseurs sont une solution viable.
Lorsque vous avez un problème d'entreprise, qui ne peut être résolu que par la transformation d'une ligne à la fois, puis un curseur est approprié.
Afin d'améliorer les performances avec le curseur, de changer le type de curseur que vous utilisez. Quelque chose que je ne connaissait pas, si vous ne spécifiez pas le type de curseur, vous déclarez, vous bénéficiez de la Dynamique Optimiste type par défaut, qui est celui qui est le plus lent pour les performances, car c'est de faire beaucoup de travail sous le capot. Toutefois, en déclarant votre curseur comme un type différent, par exemple un curseur statique, il a de très bonnes performances.
Voir ces articles pour une explication plus complète:
La Vérité Sur Les Curseurs: Partie I
La Vérité Sur les Curseurs: Partie II
La Vérité Sur les Curseurs: Partie III
Je pense que le plus gros con contre les curseurs de la performance est, cependant, pas la pose d'une mission dans un jeu basé sur l'approche serait probablement au deuxième rang. La troisième serait la lisibilité et la mise en page des tâches, comme d'habitude, ils ne ont pas beaucoup de commentaires utiles.
SQL Server est optimisé pour fonctionner l'ensemble. Vous écrivez la requête renvoie un jeu de résultats de données, comme une jointure sur les tables par exemple, mais l'exécution de SQL Server moteur détermine le rejoindre à utiliser: Jointure de Fusion, de Jointure de Boucle Imbriquée, ou Jointure de Hachage. SQL Server détermine le meilleur possible de rejoindre algorithme basé sur la participation des colonnes, volume de données, l'indexation de la structure, et l'ensemble de valeurs dans les colonnes participant. Donc à l'aide d'un ensemble en fonction de l'approche est généralement la meilleure approche dans le rendement au cours de la procédure curseur approche.
OriginalL'auteur James Drinkard