¿Separar / Adjuntar o Fuera de línea / En línea borra la memoria caché de búfer para una base de datos particular?

8

Un amigo mío me dijo hoy que en lugar de rebotar SQL Server, simplemente podría desconectar y luego volver a adjuntar una base de datos y esta acción eliminaría las páginas y los planes de la base de datos de la caché. No estoy de acuerdo y proporciono mi evidencia a continuación. Si no está de acuerdo conmigo o tiene una mejor refutación, que por todos los medios de suministro.

Estoy usando AdventureWorks2012 en esta versión de SQL Server:

SELECCIONE @@ VERSIÓN;
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Developer Edition (64 bits) en Windows NT 6.1 (compilación 7601: Service Pack 1)

Después de cargar la base de datos, ejecuto la siguiente consulta:

En primer lugar, ejecute el script de engorde AW de Jonathan K que se encuentra aquí:

AW engorda

---------------------------
- Paso 1: ¿Cosas de Bpool?
---------------------------
USE [AdventureWorks2012];
VAMOS

SELECCIONE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamaño del búfer (MB)]
   , COUNT (*) AS [buffer_count]
DESDE
     sys.allocation_units AS a
     UNIÓN INTERNA sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     UNIÓN INTERNA sys.partitions AS p
           ON a.container_id = p.hobt_id
DÓNDE
     b.database_id = DB_ID ()
     Y p.object_id> 100
AGRUPAR POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

El resultado se muestra aquí: ingrese la descripción de la imagen aquí

Separe y vuelva a adjuntar la base de datos y luego vuelva a ejecutar la consulta.

---------------------------
- Paso 2: Separar / Adjuntar
---------------------------
- Separar
USE [maestro]
VAMOS
EXEC master.dbo.sp_detach_db @dbname = N'AdventureWorks2012 '
VAMOS

- Adjuntar
USE [maestro];
VAMOS

CREAR BASE DE DATOS [AdventureWorks2012] ACTIVADO 
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Data.mdf ' 
)
    ,
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Log.ldf ' 
)
 PARA ADJUNTAR;
VAMOS

¿Qué hay en la piscina ahora?

---------------------------
- Paso 3: ¿Cosas de Bpool?
---------------------------
USE [AdventureWorks2012];
VAMOS

SELECCIONE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamaño del búfer (MB)]
   , COUNT (*) AS [buffer_count]
DESDE
     sys.allocation_units AS a
     UNIÓN INTERNA sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     UNIÓN INTERNA sys.partitions AS p
           ON a.container_id = p.hobt_id
DÓNDE
     b.database_id = DB_ID ()
     Y p.object_id> 100
AGRUPAR POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

Y el resultado: ingrese la descripción de la imagen aquí

¿Todas las lecturas son lógicas en este momento?

--------------------------------
- Paso 4: ¿Solo lecturas lógicas?
--------------------------------
USE [AdventureWorks2012];
VAMOS

CONFIGURAR ESTADÍSTICAS IO;   
    SELECT * FROM DatabaseLog;
    VAMOS
ESTABLECER ESTADÍSTICAS IO OFF;  

/ *
(1597 filas afectadas)
Tabla 'DatabaseLog'. Recuento de escaneo 1, lecturas lógicas 782, lecturas físicas 0, lecturas anticipadas 768, lecturas lógicas lob 94, lecturas físicas lob 4, lecturas lob anticipadas 24.
* /  

Y podemos ver que la agrupación de búferes no fue totalmente eliminada por la separación / conexión. Parece que mi amigo estaba equivocado. ¿Alguien está en desacuerdo o tiene una mejor discusión?

Otra opción es desconectarse y luego conectarse a la base de datos. Probemos eso.

--------------------------------
- Paso 5: fuera de línea / en línea?
--------------------------------
ALTERAR BASE DE DATOS [AdventureWorks2012] SET OFFLINE;
VAMOS
ALTERAR BASE DE DATOS [AdventureWorks2012] SET ONLINE;
VAMOS

---------------------------
- Paso 6: ¿Cosas de Bpool?
---------------------------
USE [AdventureWorks2012];
VAMOS

SELECCIONE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamaño del búfer (MB)]
   , COUNT (*) AS [buffer_count]
DESDE
     sys.allocation_units AS a
     UNIÓN INTERNA sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     UNIÓN INTERNA sys.partitions AS p
           ON a.container_id = p.hobt_id
DÓNDE
     b.database_id = DB_ID ()
     Y p.object_id> 100
AGRUPAR POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

Parece que la operación fuera de línea / en línea funcionó mucho mejor.

ingrese la descripción de la imagen aquí

fuera de línea
fuente

Respuestas:

9

Al principio pensé que estabas haciendo algo aquí. La suposición de trabajo era similar a la de que tal vez el grupo de búferes no se volcó inmediatamente ya que requiere "algo de trabajo" para hacerlo y por qué molestarse hasta que se requirió la memoria. Pero...

Su prueba es defectuosa.

Lo que está viendo en el grupo de búferes son las páginas leídas como resultado de volver a adjuntar la base de datos, no los restos de la instancia anterior de la base de datos.

Y podemos ver que la agrupación de búferes no fue totalmente eliminada por la separación / conexión. Parece que mi amigo estaba equivocado. ¿Alguien está en desacuerdo o tiene una mejor discusión?

Si. Estás interpretando physical reads 0que significa que no hubo lecturas físicas

Tabla 'DatabaseLog'. Cuenta de escaneo 1, lecturas lógicas 782, lecturas físicas 0, lecturas anticipadas 768 , lecturas lógicas lob 94, lecturas físicas lob 4, lecturas lob anticipadas 24.

Como se describe en el blog de Craig Freedman, el mecanismo de lectura anticipada secuencial intenta garantizar que las páginas estén en la memoria antes de que el procesador de consultas las solicite, por lo que se ve un conteo de lectura física cero o inferior al esperado.

Cuando SQL Server realiza un escaneo secuencial de una tabla grande, el motor de almacenamiento inicia el mecanismo de lectura anticipada para garantizar que las páginas estén en la memoria y listas para escanear antes de que el procesador de consultas las necesite. El mecanismo de lectura anticipada intenta mantenerse 500 páginas por delante del escaneo.

Ninguna de las páginas requeridas para satisfacer su consulta estaba en memoria hasta que la lectura anticipada las colocara allí.

En cuanto a por qué los resultados en línea / fuera de línea en un perfil de agrupación de almacenamiento intermedio diferente garantiza una investigación un poco más inactiva. @MarkSRasmussen podría ayudarnos con eso la próxima vez que nos visite.

Mark Storey-Smith
fuente