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.
Réponses:
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'ellemax 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.
la source
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.
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.
la source
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
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
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
la source