Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment convertir l'exécution ligne par ligne en approche basée sur SET dans SQL

Jusqu'à ce que la structure du tableau et les exemples de données de résultats attendus ne soient pas fournis, voici quelques petites choses que je vois qui peuvent être améliorées (certaines d'entre elles sont déjà mentionnées par d'autres ci-dessus) :

  1. WHILE Loop est aussi un curseur. Donc, passer à la boucle while ne va pas accélérer les choses.
  2. Utilisez le curseur LOCAL FAST_FORWARD sauf si vous avez besoin de revenir en arrière sur un enregistrement. Cela rendrait l'exécution beaucoup plus rapide.
  3. Oui, je suis d'accord qu'une approche basée sur SET serait la plus rapide dans la plupart des cas, mais si vous devez stocker un jeu de résultats intermédiaire quelque part, je suggérerais d'utiliser une table temporaire au lieu d'une variable de table. La table temporaire est un "moindre mal" entre ces 2 options. Voici quelques raisons pour lesquelles vous devriez essayer d'éviter d'utiliser une variable de table :

    • Étant donné que SQL Server n'aurait aucune statistique préalable sur la variable de table lors de la construction du plan d'exécution, il considérera toujours qu'un seul enregistrement serait renvoyé par la variable de table lors de la construction du plan d'exécution. Et en conséquence, le moteur de stockage n'attribuerait que la même quantité de mémoire RAM pour l'exécution de la requête. Mais en réalité, il pourrait y avoir des millions d'enregistrements que la variable de table pourrait contenir pendant l'exécution. Si cela se produisait, SQL Server serait obligé de déverser les données sur le disque dur pendant l'exécution (et vous verrez beaucoup de PAGEIOLATCH dans sys.dm_os_wait_stats), ce qui ralentirait considérablement les requêtes.
    • Une façon de se débarrasser du problème ci-dessus serait de fournir un indicateur de niveau d'instruction OPTION (RECOMPILE) à la fin de chaque requête où une valeur de table est utilisée. Cela obligerait SQL Server à construire le plan d'exécution de ces requêtes à chaque fois pendant l'exécution et le moindre problème d'allocation de mémoire pourrait être évité. Cependant, l'inconvénient est que SQL Server ne pourra plus tirer parti d'un plan d'exécution déjà mis en cache pour cette procédure stockée et nécessiterait une recompilation à chaque fois, ce qui détériorerait les performances dans une certaine mesure. Ainsi, à moins que vous sachiez que les données de la table sous-jacente changent fréquemment ou que la procédure stockée elle-même n'est pas fréquemment exécutée, cette approche n'est pas recommandée par les MVP Microsoft.