Il y a des requêtes où lorsque nous frappons "exécuter", il montre quelques lignes et il continue de croître, mais la requête n'est pas encore terminée. Pourtant, parfois, il attend la fin de la requête.
Pourquoi cela arrive-t-il? Y a-t-il un moyen de contrôler cela?
La réponse, comme d'habitude (d'accord, la plupart du temps), réside dans le plan d'exécution.
Certains opérateurs exigent que toutes les lignes les atteignent avant de pouvoir commencer à traiter ces lignes et à les transmettre en aval, par exemple:
Ils sont soit appelés bloquants, soit opérateurs stop and go à cause de cela, et ils sont souvent choisis lorsque l'optimiseur pense qu'il devra traiter un grand nombre de données pour trouver vos données.
Il existe d'autres opérateurs qui peuvent commencer la diffusion en continu ou transmettre immédiatement les lignes trouvées
Lorsque les requêtes commencent à renvoyer des données immédiatement, mais ne se terminent pas immédiatement, cela signifie généralement que l'optimiseur a choisi un plan pour localiser et renvoyer rapidement certaines lignes à l'aide d'opérateurs dont le coût de démarrage est inférieur.
Cela peut se produire en raison d'objectifs de ligne introduits par vous ou par l'optimiseur.
Cela peut également arriver si un mauvais plan est choisi pour une raison quelconque (manque de SARGabilité, reniflement des paramètres, statistiques insuffisantes, etc.), mais cela demande plus de fouilles pour comprendre.
Pour plus d'informations, consultez le blog de Rob Farley ici
Et la série de Paul White sur les objectifs de rang ici , ici , ici , et ici .
Il convient également de noter que, si vous parlez de SSMS, les lignes n'apparaissent qu'une fois qu'un tampon entier a été rempli, et pas seulement bon gré mal gré.
Si je comprends ce que vous observez, voici comment Management Studio rend lignes, et a peu à voir avec la façon dont SQL Server renvoie lignes. En fait, souvent lorsque vous renvoyez des résultats volumineux à SSMS et tentez de les rendre dans une grille, SSMS ne peut pas suivre et SQL Server finit par attendre que l'application traite plus de lignes. Dans ce cas, vous verrez SQL Server accumuler ASYNC_NETWORK_IO
Attente.
Vous pouvez le contrôler quelque peu en utilisant Results to Text au lieu de Results to Grid, car SSMS peut dessiner du texte plus rapidement qu'il ne peut dessiner de grilles, mais vous constaterez probablement que cela peut affecter la lisibilité en fonction du nombre de colonnes et des types de données impliqués. Les deux sont affectés par le moment où SSMS décide d'écrire réellement les résultats dans ce volet, ce qui dépend du niveau de remplissage du tampon de sortie.
Lorsque vous avez des instructions multiple et que vous souhaitez forcer le tampon à afficher les résultats de sortie dans le volet des messages, vous pouvez utiliser une petite astuce d'impression entre les instructions:
RAISERROR('', 0, 1) WITH NOWAIT;
Mais cela n'aidera pas lorsque vous essayez d'obtenir SSMS pour rendre les lignes plus rapidement lorsque toute la sortie provient d'une seule instruction.
Plus directement, vous pouvez le contrôler en limitant le nombre de résultats que vous affichez dans SSMS. Je vois souvent des gens se plaindre du temps qu'il faut pour retourner un million de lignes à la grille. Qu'est-ce que quelqu'un va faire avec un million de lignes dans une grille SSMS, je n'en ai aucune idée.
Il y a quelques hacks comme OPTION (FAST 100)
, qui optimisera pour récupérer ces 100 premières lignes (ou n'importe quelle 100 lignes s'il n'y a pas de ORDER BY
Externe), mais cela peut se faire au prix d'une récupération beaucoup plus lente pour le reste des lignes et d'un plan qui est globalement plus inefficace, donc ce n'est pas vraiment un go-to option IMHO.
Votre question ne concerne pas SQLServer en soi mais:
Existe-t-il un moyen de contrôler cela?
Réponse courte:
sqlcmd
au lieu de ssms
ou sqlcmd
- mode de ssms
Réponse longue:
Bien sûr! Mais pas n - prob
sqlcmd
ou en mode sqlcmd
- en ssms.spid
et vous obtenez la liste complète des paramètres de session. Comparer avec les paramètres de la session sqlcmd
. Si rien ne clique - copiez tous les paramètres de session du profileur dans votre script de requête, exécutez en mode sqlcmd
- et en changeant progressivement les paramètres, vous trouverez votre coupable.Bonne chance!