Quels sont les avantages d'utiliser le curseur de la base de données?

Elle est basée sur la question de l'entrevue que j'ai rencontrés.

définition très courte peut être

Il peut être utilisé pour manipuler les lignes renvoyées par une requête.

en plus de l'utilisation du curseur (les Points sont listés ici sur MSDN), j'ai une question dans mon esprit que si nous pouvons effectuer toutes les opérations en utilisant la requête ou la procédure stockée (si Je ne me trompe pas, comme nous pouvons utiliser Transact-SQL pour ms-sql), y a-t-il un point concret que nous devrions utiliser le curseur?

35
demandé sur Vikas 2010-10-05 11:17:52

5 réponses

utiliser des curseurs par rapport à de gros résultats c'est comme utiliser le streaming vidéo au lieu de télécharger une vidéo en un seul clic, et la regarder quand elle a été téléchargée. Si vous téléchargez, vous devez avoir quelques concerts de l'espace et de la patience d'attendre jusqu'à ce que le téléchargement terminé. Peu importe la vitesse de votre machine ou de votre réseau, tout le monde regarde un film à la même vitesse.

normalement toute requête est envoyée au serveur, exécutée, et le résultat envoyé sur le réseau à vous, en l'un des pics d'activité. Le curseur vous donnera l'accès à la ligne de données par ligne et chaque ligne de flux seulement quand vous la demandez (peut effectivement la voir).

  • un curseur peut vous faire gagner du temps-parce que vous n'avez pas besoin d'attendre le traitement et le téléchargement de votre recordset complet
  • il vous sauvera de la mémoire, à la fois sur le serveur et sur le client parce qu'ils n'ont pas à consacrer une grande partie de la mémoire aux résultats
  • équilibre de charge à la fois votre réseau et votre serveur-travailler en mode" burst " est généralement plus efficace, mais il peut complètement bloquer votre serveur et votre réseau. De tels délais sont rarement souhaitables pour les environnements à utilisateurs multiples. Streaming laisse de la place pour d'autres opérations.
  • permet des opérations sur les tables interrogées (sous certaines conditions) qui n'affectent pas directement votre curseur. Ainsi, pendant que vous tenez un curseur sur une ligne, d'autres processus peuvent lire, mettre à jour et même supprimer d'autres lignes. Cela aide surtout avec très occupé tables, beaucoup lit et écrit simultanément.

ce qui nous amène à quelques réserves, cependant:

  • cohérence: en utilisant un curseur, vous n'opérez pas (habituellement) sur un instantané cohérent des données, mais sur une ligne. Ainsi votre simultanéité/cohérence / isolation garantit une chute de l'ensemble de la base de données (acide) à une seule rangée. Vous pouvez généralement informer votre SGBD quel niveau de concurrence vous voulez, mais si vous êtes trop nitpicky (verrouillage de la table complète vous êtes dans), vous jeter beaucoup de l'économie des ressources sur le serveur.

  • la transmission de chaque ligne par elle-même peut être très inefficace, car chaque paquet a des négociations au-dessus de lui que vous pourriez éviter en envoyant de gros morceaux de données, peut-être compressées, par paquet. ( Aucun serveur de base de données ou bibliothèque de client N'est assez stupide pour transmettre chaque ligne individuellement, il y a la mise en cache et le chunking sur les deux extrémités, pourtant, il est pertinent.)

  • les curseurs sont plus difficiles à faire droit. Considérez une requête avec un grand ensemble de résultats, vous motivant à utiliser un curseur, qui utilise un groupe par clause avec des fonctions agrégées. (Ces requêtes sont courantes dans les entrepôts de données). Le groupe BY peut complètement détruire votre serveur, parce qu'il doit générer et stocker l'ensemble des résultats à la fois, peut-être même en tenant des serrures sur d'autres tables.

Règle de base:

  • si vous travaillez sur des petits jeux de résultats rapidement créés, n'utilisez pas de curseurs.
  • Curseurs excell sur les ad hoc, complexe (referentially), les requêtes de nature séquentielle, avec des gros jeux de résultats et de faibles exigences de cohérence.

"caractère séquentiel" signifie qu'il n'y a pas de fonctions agrégées dans le groupe lourd par des clauses dans votre requête. Le serveur peut décider paresseusement de calculer 10 lignes pour que votre curseur consomme à partir d'un cache et faire d'autres choses en attendant.

HTH

43
répondu AndreasT 2012-04-04 14:20:49

un curseur est Un outil qui vous permet de parcourir les enregistrements dans un jeu. Il a des notions de et enregistrement en cours.

en général,SQL fonctionne avec des multisets: ce sont des ensembles de disques qui se répètent peut-être dans un ordre Non donné, pris dans leur ensemble.

Dire, cette requête:

SELECT  *
FROM    a
JOIN    b
ON      b.a = a.id

, fonctionne sur multisets a et b.

rien dans cette requête ne fait des hypothèses sur l'ordre de la documents, comment ils sont stockés, dans quel ordre ils devraient être consultés, etc.

cela permet de faire abstraction des détails d'implémentation et de laisser le système essayer de choisir le meilleur algorithme possible pour exécuter cette requête.

cependant, une fois que vous aurez transformé toutes vos données, vous aurez finalement besoin d'accéder aux enregistrements de façon ordonnée et une à une.

vous ne vous souciez pas de comment exactement les entrées d'un annuaire sont stockées sur un disque dur, mais une imprimante les étiquettes de formatage doivent être appliquées à chaque enregistrement individuellement.

C'est exactement là où les curseurs entrent en jeu. Chaque fois que vous traitez un jeu de résultats du côté client, vous utilisez un curseur. Vous ne recevez pas de mégaoctets de données non triées du serveur: vous obtenez juste une variable minuscule: un descripteur de résultat, et écrivez juste quelque chose comme ceci:

while (!rs.EOF) {
   process(rs);
   rs.moveNext();
}

c'est le curseur qui implémente tout cela pour vous.

cela concerne bien sûr l'interaction base de données-client.

en ce qui concerne la base de données elle-même:à l'intérieur la base de données, vous avez rarement besoin des curseurs, puisque, comme je l'ai dit ci-dessus, presque toutes les transformations de données peuvent être mises en œuvre en utilisant des opérations de jeu plus efficacement.

Cependant, il y a des exceptions:

  • opérations AnalytiquesSQL Server sont très mal mises en oeuvre. Une somme cumulative, par exemple, pourrait être calculé beaucoup plus efficacement avec un curseur que d'utiliser les opérations basées sur des ensembles
  • traitement des données en morceaux. Il y a des cas où une opération basée sur un ensemble doit être appliquée séquentiellement à un partie d'un jeu et les résultats de chaque morceau doivent être engagés indépendamment. Bien qu'il soit encore possible de le faire en utilisant des opérations basées sur un ensemble, un curseur est souvent la meilleure façon de le faire.
  • la Récursivité dans le les systèmes qui ne supportent pas nativement.

vous pouvez aussi trouver cet article intéressant à lire:

27
répondu Quassnoi 2010-10-05 12:41:15

en utilisant un curseur, il est possible de lire de façon séquentielle à travers un ensemble de données, de manière programmatique, de sorte qu'il se comporte de manière similaire à l'accès au fichier conventionnel, plutôt que la caractéristique de comportement basée sur un ensemble de données SQL.

Il y a quelques situations où cela peut être utile:

  1. Lorsqu'il est nécessaire de simuler le comportement d'accès aux enregistrements basé sur des fichiers-par exemple, lorsqu'une base de données relationnelle est utilisée comme mécanisme de stockage de données pour un morceau de code qui a été précédemment écrit pour utiliser des fichiers indexés pour le stockage de données.

  2. Lorsqu'il est nécessaire de traiter les données de manière séquentielle - un exemple simple pourrait être de calculer un solde total courant pour un client spécifique. (Un certain nombre de bases de données relationnelles, comme Oracle et SQLServer, ont maintenant des extensions analytiques à SQL qui devraient réduire considérablement le besoin pour cela.)

inévitablement, wikipedia a plus: http://en.wikipedia.org/wiki/Database_cursor

3
répondu Josef K 2010-10-05 12:05:49

Avec le curseur, vous accédez à une rangée à la fois. Il est donc possible de l'utiliser lorsque vous voulez manipuler avec beaucoup de lignes, mais avec un seul à un moment donné.

on m'a dit à mes cours, la raison d'utiliser le curseur est que vous voulez accéder à plus de lignes que vous pouvez adapter à votre mémoire - donc vous ne pouvez pas simplement obtenir toutes les lignes dans une collection et puis boucle à travers elle.

1
répondu Hurda 2010-10-05 07:22:05

parfois, une logique basée sur un ensemble peut devenir très complexe et opaque. Dans ces cas, et si la performance n'est pas un problème, un curseur côté serveur peut être utilisé pour remplacer la logique relationnelle par une logique procédurale plus maniable et familière (pour un penseur Non relationnel), ce qui facilite la maintenance.

1
répondu Clodoaldo Neto 2012-04-04 14:41:37