2008-10-22 7 views
3

J'utilise un curseur dans ma procédure stockée. Cela fonctionne sur une base de données qui a un grand nombre de données. pour chaque élément du curseur, je fais une opération de mise à jour. Cela prend énormément de temps à compléter. Presque 25min. :(.. Y at-il de toute façon je peux réduire le temps consommé pour cela?Pourquoi mon curseur SQL Server est-il très lent?

+1

Veuillez fournir un exemple de code de ce que fait le curseur, Sinon, vous demandez combien de temps un morceau de corde est. – mjallday

Répondre

6

Lorsque vous devez faire une opération plus complexe à chaque ligne que ce qu'une simple mise à jour vous permettra, vous pouvez essayer:

  • Ecrire une fonction définie par l'utilisateur et l'utiliser dans la mise à jour (probablement encore lent)
  • données Mettez dans une table temporaire et l'utiliser une mise à jour ... dE:

Saviez-vous que sur le UPDATE ... de la syntaxe? Il est assez puissant quand les choses deviennent plus complexes:

UPDATE 
    MyTable 
SET 
    Col1 = CASE WHEN b.Foo = "Bar" THEN LOWER(b.Baz) ELSE "" END, 
    Col2 = ISNULL(c.Bling, 0) * 100/Col3 
FROM 
    MyTable 
    INNER JOIN MySecondTable AS b ON b.Id = MyTable.SecondId 
    LEFT JOIN ##MyTempTable AS c ON c.Id = b.ThirdId 
WHERE 
    MyTabe.Col3 > 0 
    AND b.Foo NOT IS NULL 
    AND MyTable.TheDate > GETDATE() - 10 

L'exemple est complètement maquillé et ne peut pas faire beaucoup de sens, mais vous obtenez l'image de la façon de faire une mise à jour plus complexe sans avoir à utiliser un curseur . Bien sûr, une table temporaire ne serait pas nécessairement nécessaire pour que cela fonctionne. :-)

7

La réponse rapide est de ne pas utiliser un curseur.Le moyen le plus efficace de mettre à jour beaucoup d'enregistrements est d'utiliser une déclaration de mise à jour. Dans les cas où vous devez utiliser un curseur plutôt qu'une instruction de mise à jour, il vous suffit d'avoir une idée de la façon dont vous écrivez l'instruction de mise à jour

Si vous avez publié un instantané de votre SQL, vous pourriez obtenir de l'aide pour réaliser ce que vous voulez.

+0

Garçon ai-je appris cela à la dure? Curseurs == lent || douloureux || db_death; –

+0

Non, pas toujours. Il existe des situations où un curseur est le moyen le plus rapide/le plus élégant/unique de résoudre un problème en SQL. Comme toujours: Il s'agit d'utiliser le bon outil pour la tâche. – Tomalak

+1

@Tomalak, je suis d'accord, parfois les curseurs sont la meilleure/seule façon de faire les choses, mais ils devraient être traités en dernier recours. Parfois, il suffit d'un œil supplémentaire pour voir la version UPDATE de la solution. – knightpfhor

1

Je voudrais éviter d'utiliser un curseur, et de travailler si possible avec des vues ou des vues matérialisées.Curseurs est quelque chose que Microsoft n'optimise pas beaucoup dans SQL Server, parce que la plupart du temps, vous devriez utiliser un instruction SQL générale (SELECT, INSERT, UPDATE, DELETE) qu'avec un curseur.

Si vous ne parvenez pas à obtenir le même résultat final même avec l'utilisation de vues ou de sous-requêtes, vous pouvez utiliser une table temporaire ou améliorer le modèle de données.

Vous ne fournissez pas beaucoup d'informations spécifiques, donc tout ce que je peux faire est de donner quelques conseils généraux.

0

Mettez-vous à jour les mêmes données que celles sur lesquelles le curseur fonctionne?

Quel type de curseur? transmettre seulement? statique? jeu de clés? dynamique?

0

La syntaxe UPDATE ... FROM mentionnée ci-dessus est la méthode préférée. Vous pouvez également faire une sous-requête comme celle-ci.

UPDATE t1 
SET t1.col1 = (SELECT top 1 col FROM other_table WHERE t1_id = t1.ID AND ...) 
WHERE ... 

Parfois, cela est la seule façon de le faire, comme chaque mise à jour de la colonne peut dépendre d'un critère differant (ou une table diferant), et il peut y avoir un « meilleur des cas » que vous souhaitez conserver bysing la ordre par clause.

0

Pouvez-vous poster plus d'informations sur le type de mise à jour que vous faites? Les curseurs peuvent être très utiles dans le bon contexte (j'en utilise beaucoup), mais si vous avez le choix entre un curseur et une opération basée sur un ensemble, la base est presque toujours le chemin à parcourir.Mais si vous n'avez pas le choix, vous n'avez pas le choix.

Je ne peux pas dire sans plus de détails.

Questions connexes