Melhor maneira de reimportar grande quantidade de dados com tempo de inatividade mínimo

11

Preciso importar cerca de 500.000 registros contendo dados de pesquisa IP (referência somente leitura) uma vez por semana (apenas três colunas int / bigint).

Eu realmente não quero me preocupar em mesclar os dados com a tabela existente. Prefiro limpar a antiga e reimportar.

O ideal é que as consultas executadas sobre os dados continuem sendo executadas (não recebemos muitas delas, e é aceitável que elas sejam executadas um pouco mais devagar enquanto a importação ocorre, mas precisam ser ativadas 24 horas por dia, sete dias por semana, portanto, execute esta " fora de horas "não é uma opção).

Coisas tentadas até agora

SSIS: Criei um pacote SSIS que trunca a tabela e importa - leva cerca de 30 segundos para ser executado (realmente muito tempo).

Tabela temporária: importar para uma tabela temporária, truncar e copiar também leva cerca de 30 segundos.

BCP: A importação em massa também é muito lenta (por algum motivo, é mais lenta que o SSIS (mesmo sem índices para manter) - acho que é algo a ver com as transações char-> int / bigint: /

Mesa de espelho? Então, no momento, estou pensando em ler a tabela através de uma visualização, importar os dados em uma tabela espelhada e alterar a visualização para apontar para esta tabela ... isso parece rápido, mas parece minúsculo um pouco hacky para mim.

Parece que isso deve ser um problema comum, mas não consigo encontrar práticas recomendadas - todas as idéias serão muito apreciadas!

obrigado

Marca
fonte

Respostas:

13

Uma solução que eu usei no passado (e já recomendei aqui e no StackOverflow antes) é criar dois esquemas adicionais:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Agora crie uma imitação da sua tabela no cacheesquema:

CREATE TABLE cache.IPLookup(...columns...);

Agora, quando você estiver executando sua operação de switch:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

Isso será mais complicado se você tiver chaves estrangeiras e outras dependências (já que pode ser necessário descartá-las e recriá-las) e, é claro, invalida completamente as estatísticas etc., e isso, por sua vez, pode afetar os planos, mas se o o mais importante é obter dados precisos na frente de seus usuários com o mínimo de interrupção; essa pode ser uma abordagem a considerar.

Aaron Bertrand
fonte
Obrigado, outra alternativa interessante - acho que as duas últimas instruções não estão certas, devem mover a sombra para o cache e truncar o cache. Gostaria de saber se o sinônimos também poderia ser usado?
Mark
Você está certo, eu confundi isso. Não sei exatamente como os sinônimos seriam melhores, acho que também é uma abordagem - tenha uma visão que aponte para um sinônimo e altere o sinônimo subjacente em uma transação quando você preencher a outra versão. Pessoalmente, acho isso um pouco melhor - quando você está consultando o dbo.IPLookup, sabe que é a tabela "atual" sem precisar procurar a visualização e o sinônimo.
Aaron Bertrand
Para sua informação, escrevi sobre isso com mais detalhes nesta semana: sqlperformance.com/2012/08/t-sql-queries/…
Aaron Bertrand