Comment SQL Server gère-t-il les données d'une requête où il n'y a pas assez de place dans le cache de tampon?

10

Ma question est de savoir comment SQL Server gère une requête qui doit extraire plus de volume de données dans le cache de tampon qu'il n'y a d'espace disponible? Cette requête contiendrait plusieurs jointures, de sorte que le jeu de résultats n'existe pas déjà dans ce format sur le disque et qu'il faudrait compiler les résultats. Mais même après la compilation, il nécessite toujours plus d'espace que ce qui est disponible dans le cache de tampon.

Je vais vous donner un exemple. Supposons que vous disposiez d'une instance SQL Server qui dispose d'un total de 6 Go d'espace de mémoire tampon tampon. J'exécute une requête avec plusieurs jointures qui lit 7 Go de données, comment SQL Server est-il en mesure de répondre à cette demande? Stocke-t-il temporairement les données dans tempdb? Cela échoue-t-il? Fait-il quelque chose qui ne fait que lire les données du disque et compile les segments à la fois?

De plus, que se passe-t-il si j'essaie de renvoyer 7 Go de données au total, cela change-t-il la façon dont SQL Server les gère?

Je suis déjà au courant de plusieurs façons de résoudre ce problème, je suis simplement curieux de savoir comment SQL Server gère cette demande en interne lorsqu'elle s'exécute comme indiqué.

De plus, je suis sûr que cette information existe quelque part, mais je n'ai pas réussi à la trouver.

Dustin
la source
1
En termes simples, SQL Server stockera les tables de travail et les résultats de son propre traitement interne dans tempdb. Les pages sont lues à partir du disque si nécessaire. Les pages resteront en mémoire jusqu'à ce qu'elles soient expulsées, ou lorsque SQL est prêt à les valider sur le disque. C'est lorsque vous exécutez une grande requête que tempdb augmentera. J'ai vu des requêtes mettre un système à genoux car tempdb était autorisé à croître sans contrôle et consommait tout l'espace restant sur le disque. Je sais que ce n'est pas exact à 100%, j'essaie simplement de l'expliquer simplement. La partie qui utilise les données n'est pas la partie qui gère l'emplacement de ces données
datagod

Réponses:

13

Les pages sont lues en mémoire selon les besoins, s'il n'y a pas de mémoire libre disponible, la page la plus ancienne non modifiée est remplacée par la page entrante.

Cela signifie que si vous exécutez une requête qui nécessite plus de données que la mémoire ne peut en contenir, de nombreuses pages auront une durée de vie très courte en mémoire, ce qui entraînera beaucoup d'E / S.

Vous pouvez voir cet effet en consultant le compteur «Durée de vie de la page» dans l'Analyseur de performances Windows. Regardez https://sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-expectancy pour de grands détails sur ce compteur.

Dans les commentaires, vous avez demandé spécifiquement ce qui se passe lorsque les résultats de la requête sont supérieurs à l'espace tampon disponible. Prenons l'exemple le plus simple, select * from some_very_big_table;supposez que la table fait 32 Go et qu'elle max server memory (MB)est configurée à 24 Go. Toutes les 32 Go de données de table seront lues dans les pages du tampon de pages une par une, verrouillées, formaté en paquets réseau et envoyé sur le câble. Cela se produit page par page; vous pouvez avoir 300 requêtes de ce type exécutées en même temps, et en supposant qu'aucun blocage ne se produise, les données de chaque requête seront lues dans l'espace tampon de page, une page à la fois, et mises sur le câble aussi vite que le client le pourra demander et consommer les données. Une fois que toutes les données de chaque page ont été envoyées sur le fil, la page se déverrouille et sera très rapidement remplacée par une autre page du disque.

Dans le cas d'une requête plus complexe, par exemple en agrégeant les résultats de plusieurs tables, les pages seront tirées en mémoire exactement comme ci-dessus car elles sont requises par le processeur de requêtes. Si le processeur de requêtes a besoin d'un espace de travail temporaire pour calculer les résultats, il le saura dès le départ lorsqu'il compilera un plan pour la requête et demandera un espace de travail (mémoire) à SQLOS . SQLOS sera à un moment donné ( en supposant qu'il n'a pas à temps ), accorder que la mémoire au processeur de requête, au cours de laquelle le traitement point de requête reprendra. Si le processeur de requêtes fait une erreur dans son estimation de la quantité de mémoire à demander à SQLOS, il peut avoir besoin d'effectuer un "déversement sur le disque"opération, où les données sont temporairement écrites dans tempdb sous une forme intermédiaire. Les pages qui ont été écrites dans tempdb seront déverrouillées une fois qu'elles auront été écrites dans tempdb pour faire de la place pour que d'autres pages soient lues en mémoire. Finalement, le processus de requête retournera aux données stockées dans tempdb, en paginant cela en utilisant le verrouillage, dans les pages du tampon qui sont marquées comme libres.

Je manque sans aucun doute une charge de détails très techniques dans le résumé ci-dessus, mais je pense que cela capture l'essence de la façon dont SQL Server peut traiter plus de données que la mémoire ne peut en contenir.

Max Vernon
la source
Par curiosité, quel type de requête tire 7 Go de données? J'espère que c'est un processus par lots.
datagod
Probablement pas beaucoup et vous avez raison, ce serait, espérons-le, un processus par lots. J'étais juste curieux de voir comment SQL traiterait cette demande
Dustin
5

Je ne peux pas parler de ce que ferait exactement votre requête dans ce scénario, mais SQL Server dispose de plusieurs options selon le montant nécessaire.

  • Les données peuvent «déborder» sur TempDB, ce serait utiliser votre disque
  • Les anciennes pages peuvent être poussées hors de votre cache tampon
  • SQL Server peut charger certaines pages dans le cache du tampon, les utiliser, puis faire pivoter de nouvelles pages dans

La meilleure façon de savoir ce qui se passerait est de créer le scénario dans un environnement de développement et de le découvrir.

Arthur D
la source
2

Ma question est de savoir comment SQL Server gère une requête qui doit extraire plus de volume de données dans le cache de tampon, puis il y a de l'espace disponible

Pour répondre à cette partie spécifique, laissez-moi vous expliquer comment cela est géré. Les pages sont de taille 8 Ko. Lorsque vous exécutez une requête demandant un ensemble de données volumineux et qui nécessite que de nombreuses pages soient mises en mémoire, SQL Server n'amènera pas toutes les pages en une seule fois. Il localisera les pages spécifiques et apportera une par une des pages de 8 Ko en mémoire, lira les données et vous donnera le résultat, ce qui continuera maintenant supposons qu'il fait face à une situation où la mémoire est inférieure dans ce cas, les anciennes pages seront vidées le disque comme @Max l'a souligné. Comme vous l'avez deviné correctement, cette mémoire insuffisante peut ralentir les choses car un certain temps serait consacré à la suppression des anciennes pages. C'est là que Checkpoint et Lazywriterentre en photo. Lazywriter doit s'assurer que la mémoire disponible est toujours là pour apporter de nouvelles pages sur le disque. Lorsque le tampon libre faible est rencontré, il est déclenché et crée des espaces libres pour être de nouvelles pages.

ÉDITER

Je comprends cela, mais la partie qui me déroute un peu est ce qui se passe si vous joignez \ filtrer des données et que ces résultats dépassent la taille du cache.

La mémoire pour la jonction et le filtrage est décidée avant même que la requête s'exécute et suppose qu'il y a vraiment un resserrement de la mémoire et que la mémoire requise pour exécuter l'opération n'est pas disponible. Le processeur SQL Server accordera la "mémoire requise" qui est

Mémoire requise: Mémoire minimale requise pour exécuter le tri et la jointure par hachage. Il est appelé obligatoire car une requête ne démarre pas sans cette mémoire disponible. Le serveur SQL utilise cette mémoire pour créer des structures de données internes pour gérer le tri et la jointure par hachage.

Ainsi, au moins la requête commencera à s'exécuter, mais pendant l'exécution, il est très probable que le résultat intermédiaire se répande à Tempdb, ce qui le ralentit. Je vous suggère fortement de lire Comprendre la subvention de mémoire de requête

Shanky
la source
Je comprends cela, mais la partie qui me déroute un peu est ce qui se passe si vous joignez \ filtrer des données et que ces résultats dépassent la taille du cache. Les données devraient être compilées pour produire l'ensemble de retour, mais l'ensemble de retour est supérieur à la taille du cache. Est-ce que les pages parcourent en interne le cache jusqu'à ce qu'elles produisent le résultat final? Ma pensée serait qu'il écrirait les résultats dans tempdb car il a dépassé le cache puis lu sur le disque, mais je ne sais pas si c'est le cas
Dustin
2
@Dustin Modifié ma réponse, veuillez vérifier
Shanky