Est-ce que Détacher / Attacher ou Hors ligne / En ligne efface le cache de tampon pour une base de données particulière?

8

Un de mes amis m'a dit aujourd'hui qu'au lieu de faire rebondir SQL Server, je pouvais simplement détacher puis rattacher une base de données et cette action effacerait les pages et les plans de la base de données donnée du cache. Je suis en désaccord et je fournis ma preuve ci-dessous. Si vous n'êtes pas d'accord avec moi ou avez une meilleure réfutation, fournissez-la par tous les moyens.

J'utilise AdventureWorks2012 sur cette version de SQL Server:

SELECT @@ VERSION;
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Developer Edition (64 bits) sur Windows NT 6.1 (Build 7601: Service Pack 1)

Après avoir chargé la base de données, j'exécute la requête suivante:

Tout d'abord, exécutez le script d'engraissement AW de Jonathan K trouvé ici:

AW Get Fat

---------------------------
- Étape 1: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
ALLER

SÉLECTIONNER
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [taille du tampon (Mo)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS p
           ON a.container_id = p.hobt_id
OÙ
     b.database_id = DB_ID ()
     ET p.object_id> 100
PAR GROUPE
     p.object_id
   , p.index_id
COMMANDÉ PAR
     buffer_count DESC;

Le résultat est affiché ici: entrez la description de l'image ici

Détachez et rattachez la base de données, puis réexécutez la requête.

---------------------------
- Étape 2: détacher / attacher
---------------------------
- Détacher
UTILISER [maître]
ALLER
EXEC master.dbo.sp_detach_db @dbname = N'AdventureWorks2012 '
ALLER

-- Attacher
UTILISER [maître];
ALLER

CRÉER UNE BASE DE DONNÉES [AdventureWorks2012] ON 
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Data.mdf ' 
)
    ,
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Log.ldf ' 
)
 POUR FIXER;
ALLER

Qu'y a-t-il dans le pool maintenant?

---------------------------
- Étape 3: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
ALLER

SÉLECTIONNER
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [taille du tampon (Mo)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS p
           ON a.container_id = p.hobt_id
OÙ
     b.database_id = DB_ID ()
     ET p.object_id> 100
PAR GROUPE
     p.object_id
   , p.index_id
COMMANDÉ PAR
     buffer_count DESC;

Et le résultat: entrez la description de l'image ici

Toutes les lectures sont-elles logiques à ce stade?

--------------------------------
- Étape 4: lectures logiques uniquement?
--------------------------------
USE [AdventureWorks2012];
ALLER

ACTIVER STATISTIQUES IO;   
    SELECT * FROM DatabaseLog;
    ALLER
DÉSACTIVER LES STATISTIQUES IO;  

/ *
(1597 ligne (s) affectée (s))
Tableau «DatabaseLog». Nombre de balayages 1, lectures logiques 782, lectures physiques 0, lectures anticipées 768, lectures logiques lob 94, lectures physiques lob 4, lectures anticipées lob 24.
* /  

Et nous pouvons voir que le pool de tampons n'a pas été totalement emporté par le détachement / attachement. On dirait que mon copain avait tort. Quelqu'un est-il en désaccord ou a-t-il un meilleur argument?

Une autre option consiste à déconnecter puis à mettre en ligne la base de données. Essayons cela.

--------------------------------
- Étape 5: Hors ligne / en ligne?
--------------------------------
ALTER DATABASE [AdventureWorks2012] SET OFFLINE;
ALLER
ALTER DATABASE [AdventureWorks2012] SET ONLINE;
ALLER

---------------------------
- Étape 6: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
ALLER

SÉLECTIONNER
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [taille du tampon (Mo)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS p
           ON a.container_id = p.hobt_id
OÙ
     b.database_id = DB_ID ()
     ET p.object_id> 100
PAR GROUPE
     p.object_id
   , p.index_id
COMMANDÉ PAR
     buffer_count DESC;

Il semble que l'opération hors ligne / en ligne ait beaucoup mieux fonctionné.

entrez la description de l'image ici

sans fil
la source

Réponses:

9

J'ai d'abord pensé que vous étiez sur quelque chose ici. L'hypothèse de travail allait dans le sens que le pool de tampons n'était peut-être pas immédiatement vidé car il nécessitait "un peu de travail" pour le faire et pourquoi s'embêter jusqu'à ce que la mémoire soit requise. Mais...

Votre test est imparfait.

Ce que vous voyez dans le pool de mémoire tampon, ce sont les pages lues à la suite de la réattachement de la base de données, pas les restes de l'instance précédente de la base de données.

Et nous pouvons voir que le pool de tampons n'a pas été totalement emporté par le détachement / attachement. On dirait que mon copain avait tort. Quelqu'un est-il en désaccord ou a-t-il un meilleur argument?

Oui. Vous interprétez physical reads 0comme signifiant qu'il n'y avait pas de lectures physiques

Tableau «DatabaseLog». Nombre de balayages 1, lectures logiques 782, lectures physiques 0, lectures anticipées 768 , lectures logiques lob 94, lectures physiques lob 4, lectures anticipées lob 24.

Comme décrit sur le blog de Craig Freedman, le mécanisme de lecture anticipée séquentielle essaie de s'assurer que les pages sont en mémoire avant d'être demandées par le processeur de requêtes, c'est pourquoi vous voyez zéro ou un nombre de lectures physiques inférieur à celui attendu.

Lorsque SQL Server effectue une analyse séquentielle d'une grande table, le moteur de stockage lance le mécanisme de lecture anticipée pour garantir que les pages sont en mémoire et prêtes à être analysées avant qu'elles ne soient nécessaires au processeur de requêtes. Le mécanisme de lecture anticipée tente de conserver 500 pages avant la numérisation.

Aucune des pages requises pour satisfaire votre requête n'était en mémoire jusqu'à ce que la lecture anticipée les y place.

Quant à savoir pourquoi les résultats en ligne / hors ligne dans un profil de pool de tampons différent justifient une enquête un peu plus inactive. @MarkSRasmussen pourrait nous aider lors de sa prochaine visite.

Mark Storey-Smith
la source