Geralmente é mais rápido selecionar em uma tabela temporária do que selecionar em uma tabela real?

Pensei ter lido em algum lugar que escrever em tempdb é mais rápido do que uma tabela real fora de tempdb. Isso é verdade de alguma forma? Achei que me lembrava dele dizendo algo especial sobre tempdb e armazenar os dados na memória?

Resposta

escrever em tempdb é mais rápido do que em uma tabela real fora de tempdb

É verdade. Existem dois aprimoramentos de IO em TempDb.

As gravações em uma tabela em um banco de dados do usuário devem ter seus registros de log liberados para o disco na confirmação ou, se uma inserção minimamente registrada (como SELECT … INTO), as páginas do banco de dados devem ser descarregadas no disco na confirmação. A maneira como o registro mínimo funciona em um banco de dados do usuário é que as páginas do banco de dados são gravadas diretamente no disco. No momento em que SELECT … INTO for concluído, as novas páginas serão todas gravadas nos arquivos físicos.

As gravações de TempDb não precisam ser descarregadas no disco na confirmação, pois o TempDb nunca é recuperado após uma falha. Portanto, eles simplesmente não são. Suas alterações geram registros de log, mas o buffer de log é liberado para o disco apenas quando está cheio, não para cada confirmação.

E desde o SQL Server 2014 , as inserções minimamente registradas no TempDb nem sempre são gravadas no disco. Se você carregar um pequeno, tabela temporária de curta duração, pode nunca ser gravado no disco. O log terá alguns registros sobre as alocações de páginas e entradas de metadados para a tabela, mas é isso.

EG execute o seguinte lote em tempdb, um banco de dados de recuperação completa e um banco de dados de recuperação simples para ver as diferenças.

drop table if exists foo go declare @data bigint declare @log bigint select @log = sum(case when type_desc = "LOG" then num_of_bytes_written end) ,@data = sum(case when type_desc = "ROWS" then num_of_bytes_written end) from sys.database_files f cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs select * into foo from sys.objects select -@log + sum(case when type_desc = "LOG" then num_of_bytes_written end) log_bytes ,-@data + sum(case when type_desc = "ROWS" then num_of_bytes_written end) data_bytes , (select recovery_model_desc from sys.databases where database_id = db_id()) recovery_model from sys.database_files f cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs 

e você verá algo como:

Para recuperação simples:

log_bytes data_bytes recovery_model -------------------- -------------------- --------------- 24576 16384 SIMPLE 

para recuperação completa:

log_bytes data_bytes recovery_model -------------------- -------------------- --------------- 36864 0 FULL 

e para tempdb:

log_bytes data_bytes recovery_model -------------------- -------------------- --------------- 0 0 SIMPLE 

Às vezes, para tempdb, você verá o buffer de log liberado:

log_bytes data_bytes recovery_model -------------------- -------------------- --------------- 61440 0 SIMPLE 

Comentários

  • Há um caso em que a inserção inicial é mais rápida, mas ela volta para mordê-lo depois. Esta demonstração mostra uma consulta trazendo dados para o cache de buffer demorando muito mais, pois o gravador lento está ocupado gravando em páginas tempdb do disco que estão sujas para uma tabela temporária que não existe mais youtube .com / watch? v = X60ipwYv1Ms & feature = youtu.be
  • Sim. Há ' s um potencial aprimoramento futuro para eliminar a liberação de páginas do Buffer Pool não alocadas a nenhum objeto. Mas carregar uma grande tabela temporária sempre impulsionará o IO, seja direta ou indiretamente, reduzindo a memória disponível para armazenamento em cache.

Resposta

Bem como grava em tempdb, muitas vezes nem todo IO de disco / rede atingido, conforme estendido na resposta de David Browne , dependendo de seu IO configuração você pode descobrir que mesmo quando os dados são grandes o suficiente para ter que ser transferidos para o disco, ainda é mais rápido do que selecionar em uma tabela “normal”:

  • O TempDB pode estar em outro drives, então tem sua própria largura de banda IO. Isso é especialmente significativo com drives giratórios em vez de SSDs. Ler de e gravar no mesmo banco de dados (ou outro banco de dados nas mesmas unidades) envolverá mais movimentos da cabeça, que adicione mais latência de IO e potencialmente limitará sua largura de banda de IO efetiva. Copiar dados entre bancos de dados em unidades / matrizes diferentes não terá a mesma latência extra.

  • TempDB pode até estar em fa mídia esterilizada do que seu armazenamento principal. Talvez em unidades locais onde o armazenamento principal está na rede, ou SSDs NVMe onde o armazenamento principal está em unidades tradicionais.

Ambas as diferenças também podem ser vistas dentro do mesmo banco de dados se você usar vários grupos de arquivos para distribuir partes dos dados entre diferentes unidades / matrizes.

O oposto também pode ser verdadeiro se você tiver vários bancos de dados que estão ativamente em uso. Como TempDB é um recurso compartilhado, ele e as unidades / rede que o hospedam podem estar sob mais carga do que os arquivos de dados de qualquer banco de dados individual.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *