Estou importando uma grande quantidade de dados para um banco de dados vazio e, antes de começar, desabilitei todos os índices não clusterizados não exclusivos para ver se eu poderia melhorar o desempenho da importação.
Agora, quero reativar os índices e estou pensando se há algo que eu possa fazer para otimizar isso.
Existem> 100 tabelas e quase 2.000 índices a serem reconstruídos. O banco de dados tem 200 GB de tamanho.
A seção principal do script que estou executando é a seguinte:
declare c_toggle_index cursor FORWARD_ONLY READ_ONLY for
select 'alter index ' + QUOTENAME(i.name) + ' on ' + o.name + ' rebuild'
from sys.indexes as i
Inner Join sys.objects o
On o.object_id = i.object_id
Where o.is_ms_shipped = 0
And i.index_id >= 1
and i.type > 1
and i.is_disabled = 1
Eu considerei definir ONLINE = OFF para a instrução alter index, mas como os índices começam desativados, eu não tinha certeza de que essa configuração teria algum efeito. Também considerei definir SORT_IN_TEMPDB = ON, mas como os arquivos tempdb estão na mesma unidade que os arquivos .mdf dos bancos de dados, presumi que também não havia nenhum benefício em fazer isso.
Durante a execução do script de reconstrução, notei que tenho muitos tipos de espera CXPACKET. Eu realmente não entendo por que isso seria ou se é um problema que eu deveria estar procurando resolver.
Um último ponto que pode ser relevante: meu servidor inteiro está inativo no momento, além dessa importação de dados no banco de dados. Não há outra atividade do usuário para considerar ou se preocupar; minha única preocupação é importar os dados para o banco de dados no menor tempo possível.
fonte
CXPACKET
esperas: o índice é reconstruído por si próprio, os índices de varredura (mesmo o índice sendo reconstruído ) e essas varreduras podem usar paralelismo. Você não deve se preocupar com essas esperas - o paralelismo provavelmente está ajudando.Respostas:
Atingir o desempenho ideal de importação neste cenário requer três coisas:
Registro Mínimo
A obtenção de inserções minimamente registradas em uma tabela em cluster vazia sem índices não clusterizados requer:
SIMPLE
ou deBULK_LOGGED
banco de dadosTABLOCK
eORDER
dicas)Nota:
Criando índices não clusterizados separadamente
As vantagens de fazer isso são:
CREATE INDEX
é registrado minimamente se o modelo de recuperação não forFULL
Evitando leituras físicas
Idealmente, os dados a serem importados serão armazenados em uma máquina separada ou, pelo menos, em um armazenamento físico separado daquele usado para hospedar o banco de dados.
O servidor de banco de dados deve ter memória suficiente para armazenar a maior tabela base no cache, com sobras suficientes para as operações de classificação necessárias ao criar índices não clusterizados.
Um bom padrão é carregar rapidamente a tabela base (carregamento de índice clusterizado minimamente registrado) e criar todos os índices não clusterizados para essa tabela enquanto suas páginas de dados ainda estiverem em cache.
A pergunta descreve um processo pelo qual as tabelas base são carregadas primeiro e, em seguida, construídos os índices não clusterizados. A definição do cursor não usa uma
ORDER BY
cláusula para pelo menos agrupar compilações de índice não clusterizadas na mesma tabela.O resultado provável é que as páginas de dados para tabelas diferentes sejam lidas repetidamente no cache e descartadas à medida que os índices não clusterizados são criados em uma ordem não determinística.
O custo de leituras físicas repetidas domina completamente os benefícios do registro mínimo obtido com a criação de índices não clusterizados separadamente. Isso explica por que você descobriu que carregar tabelas com índices existentes é mais rápido (porque todos os índices não clusterizados para uma determinada tabela são mantidos antes de passar para a próxima tabela).
Sumário
O processo de importação deve ser reformulado para carregar em massa uma tabela por vez. Isso significa carregar a tabela e criar todos os índices não clusterizados antes de passar para o próximo. A instância do SQL Server deve ter memória suficiente disponível para armazenar a maior tabela e executar a maior classificação de índice não clusterizado ao mesmo tempo.
Você também pode tentar ativar o TF 610 antes de carregar os dados em tabelas com índices não clusterizados já em vigor. Geralmente não é tão rápido quanto o método anterior, mas pode ser rápido o suficiente.
Consulte o seguinte para obter mais informações:
O Guia de Desempenho de Carregamento de Dados
Operações que podem ser registradas minimamente
fonte