Desanexar / Anexar ou Off-line / Online limpa o cache do buffer para um banco de dados específico?

8

Um amigo meu me disse hoje que, em vez de devolver o SQL Server, eu poderia simplesmente desanexar e reconectar um banco de dados, e essa ação limparia as páginas e os planos do banco de dados fornecidos do cache. Discordei e forneço minhas evidências abaixo. Se você discorda de mim ou tem uma refutação melhor, do que por qualquer meio forneça-a.

Estou usando o AdventureWorks2012 nesta versão do SQL Server:

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

Depois de carregar o banco de dados, eu executo a seguinte consulta:

Em primeiro lugar, execute o script de engorda AW de Jonathan K encontrado aqui:

AW Get Fat

---------------------------
- Etapa 1: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
VAI

SELECT
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamanho do buffer (MB)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units como um
     JUNÇÃO INTERNA 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
ONDE
     b.database_id = DB_ID ()
     AND p.object_id> 100
GRUPO POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

O resultado é mostrado aqui: insira a descrição da imagem aqui

Desanexe e reconecte o banco de dados e execute novamente a consulta.

---------------------------
- Etapa 2: desanexar / anexar
---------------------------
- Destacar
USE [mestre]
VAI
EXEC master.dbo.sp_detach_db @dbname = N'AdventureWorks2012 '
VAI

- Anexar
USE [mestre];
VAI

CRIAR BASE DE DADOS [AdventureWorks2012] LIGADO 
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Data.mdf ' 
)
    ,
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Log.ldf ' 
)
 PARA ANEXAR;
VAI

O que há no bpool agora?

---------------------------
- Etapa 3: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
VAI

SELECT
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamanho do buffer (MB)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units como um
     JUNÇÃO INTERNA 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
ONDE
     b.database_id = DB_ID ()
     AND p.object_id> 100
GRUPO POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

E o resultado: insira a descrição da imagem aqui

Todas as leituras são lógicas neste momento?

--------------------------------
- Etapa 4: somente leituras lógicas?
--------------------------------
USE [AdventureWorks2012];
VAI

ESTATÍSTICAS LIGADAS;   
    SELECT * FROM DatabaseLog;
    VAI
DESLIGAR ESTATÍSTICAS IO;  

/ *
(1597 linhas afetadas)
Tabela 'DatabaseLog'. Contagem de varreduras 1, leituras lógicas 782, leituras físicas 0, leituras de leitura antecipada 768, leituras lógicas de lob 94, leituras físicas de lob 4, leituras físicas de lob 4, leituras de leitura antecipada de lob 24.
* /  

E podemos ver que o buffer pool não foi totalmente deslumbrado com a desanexação / conexão. Parece que meu amigo estava errado. Alguém discorda ou tem um argumento melhor?

Outra opção é offline e, em seguida, online o banco de dados. Vamos tentar isso.

--------------------------------
- Etapa 5: offline / online?
--------------------------------
ALTER DATABASE [AdventureWorks2012] SET OFFLINE;
VAI
ALTER DATABASE [AdventureWorks2012] SET ONLINE;
VAI

---------------------------
- Etapa 6: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
VAI

SELECT
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [tamanho do buffer (MB)]
   , COUNT (*) AS [buffer_count]
DE
     sys.allocation_units como um
     JUNÇÃO INTERNA 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
ONDE
     b.database_id = DB_ID ()
     AND p.object_id> 100
GRUPO POR
     p.object_id
   , p.index_id
ORDENAR POR
     buffer_count DESC;

Parece que a operação offline / online funcionou muito melhor.

insira a descrição da imagem aqui

ooutwire
fonte

Respostas:

9

Inicialmente, pensei que você estivesse pensando em algo aqui. A suposição de trabalho foi semelhante à de que talvez o buffer pool não tenha sido liberado imediatamente, pois requer "algum trabalho" para fazê-lo e por que se preocupar até que a memória seja necessária. Mas...

Seu teste é falho.

O que você vê no pool de buffers são as páginas lidas como resultado de anexar novamente o banco de dados, não os restos da instância anterior do banco de dados.

E podemos ver que o buffer pool não foi totalmente deslumbrado com a desanexação / conexão. Parece que meu amigo estava errado. Alguém discorda ou tem um argumento melhor?

Sim. Você está interpretando physical reads 0como significando que não houve leituras físicas

Tabela 'DatabaseLog'. Contagem de varreduras 1, leituras lógicas 782, leituras físicas 0, leituras de pré-leitura 768 , leituras lógicas de lob 94, leituras físicas de lob 4, leituras de lob 4, leituras de leitura antecipada 24.

Conforme descrito no blog de Craig Freedman, o mecanismo de leitura sequencial antecipada tenta garantir que as páginas estejam na memória antes de serem solicitadas pelo processador de consultas, e é por isso que você vê zero ou uma contagem física de leitura menor que o esperado relatada.

Quando o SQL Server executa uma varredura seqüencial de uma tabela grande, o mecanismo de armazenamento inicia o mecanismo de leitura antecipada para garantir que as páginas estejam na memória e prontas para varredura antes de serem necessárias pelo processador de consultas. O mecanismo de leitura antecipada tenta ficar 500 páginas à frente da digitalização.

Nenhuma das páginas necessárias para satisfazer sua consulta estava na memória até a leitura antecipada as colocar lá.

Por que os resultados online / offline em um perfil de buffer pool diferente justificam uma investigação um pouco mais inativa. @MarkSRasmussen pode nos ajudar com isso na próxima vez que ele visitar.

Mark Storey-Smith
fonte