Eu tenho um banco de dados SQL hospedado no Azure. O problema é que o tamanho está ficando fora de controle. Posso ver até 99% de fragmentação nos índices de cluster da Chave Primária.
Sou capaz de reconstruir todos os outros índices com a online=on
opção e isso não afeta o desempenho. O tamanho de um dos índices PK Clustered é maior que 200 GB e, nesse caso, REBUILD...WITH (ONLINE=ON)
causa um bloqueio.
Temos usuários de todos os fusos horários acessando o site, então, não consigo encontrar um horário para reconstruir o índice offline.
Qual é a melhor estratégia para reconstruir índices grandes sem ter um tempo de inatividade no site?
Acredito que a reorganização não ajudará, pois a fragmentação é de 99%. O problema é que a tabela fica bloqueada mesmo com a online. O principal problema é que o índice é maior que 200 GB. A chave primária é um número inteiro.
REORGANIZE
reduzirá a fragmentação das páginas em folhas e o espaço compactoREBUILD
, apenas com menos eficiência. Você tem certeza de que o tamanho grande é devido à fragmentação? Qual é o fator de preenchimento?Respostas:
Mesmo que seja um pouco tarde, vou responder com a esperança de que ajude ou pelo menos rejeite algumas idéias / comentários adicionais sobre esse assunto, porque acho que é uma boa pergunta.
Primeiro, e não sei se você está fazendo isso ou não, mas por favor, não assuma que altos níveis de fragmentação no índice sempre causam desempenho ruim. Estatísticas antigas (por exemplo, sys.dm_db_stats_properties ) e grandes quantidades de espaço em branco por página (por exemplo, avg_page_space_used_in_percent na coluna sys.dm_db_index_physical_stats dmv ) têm mais relevância em relação aos problemas de desempenho do que apenas à fragmentação. Sim, índices altamente fragmentados geram mais leituras antecipadas e você normalmente vê estatísticas obsoletas e níveis mais altos de espaço em branco por página, juntamente com a fragmentação, mas a fragmentação não está diretamente ligada às otimizações do plano de consulta nem à quantidade de memória que carrega o índice do disco vai realmente consumir. Os planos de consulta são afetados pelas estatísticas e sua pegada de memória incha com mais espaço em branco . Por exemplo, um índice fragmentado em 99%, mas com menos de 5% em média. É provável que o espaço em branco e as estatísticas atualizadas não estejam causando problemas drásticos de desempenho em comparação com um plano de execução ruim como resultado de estatísticas obsoletas ou paginação constante de um índice grande demais para caber na memória porque há uma quantidade significativa de espaço em branco presente por página.
Se a fragmentação é realmente um problema , você pode reduzi-la, online, emitindo uma
ALTER INDEX ... REORGANIZE
declaração conforme identificado por Dan Guzman nos comentários. Isso não criará um índice tão otimizado quanto umaREBUILD
operação, mas reduzirá sua fragmentação. A chave aqui é identificar janelas de menor uso em seu banco de dados e executá-lo. Isso pode levar 15 minutos ou várias horas, obviamente quanto mais, melhor, mas a chave aqui é que essa operação não reverte e retém qualquer progresso feito, mesmo que você a mate no meio da execução.Se, em um mundo perfeito onde sua fragmentação foi eliminada, faria mais sentido utilizar o particionamento nesta tabela? O Banco de Dados SQL do Azure permite o particionamento de tabela e a Microsoft tem um ótimo artigo descrevendo algumas estratégias de particionamento para o Banco de Dados SQL do Azure . Se seus dados não forem voláteis, o particionamento pode ajudar a reduzir as necessidades de manutenção e, se combinado com a compactação de tabela , você também poderá reduzir seu espaço de armazenamento geral. A resposta anterior de Alberto Murillo faz alusão à utilização do particionamento horizontal com base em uma região de dados, e essa abordagem pode ajudar a criar algumas janelas de manutenção para você, pois seus dados seriam mais específicos por região, em vez de globais.
A transição para uma tabela particionada não será fácil com a sua ausência atual de janelas de manutenção, mas você poderá utilizar uma abordagem descrita por Maria Zakourdaev que usa Visualizações Particionadas na parte superior da tabela atual e uma nova tabela particionada para iniciar o particionamento. dados futuros. À medida que o tempo passa (e esperamos que seus dados antigos sejam eliminados), você pode eventualmente fazer a transição completa para a tabela particionada. Novamente, não conheço seus dados ou aplicativo, mas talvez essa abordagem seja algo que você possa empregar.
fonte
Primeiro, é importante considerar se a fragmentação é importante.
Se sua consulta estiver apenas fazendo buscas em linha única, talvez você não note fragmentação. Nas SANs modernas, o cache no nível da SAN pode fazer com que as IO phyiscal sejam rápidas o suficiente para que a fragmentação não importe. No SSD, o padrão aleatório de E / S causado pela varredura de um índice fragmentado pode realmente resultar em melhor desempenho que os dados não fragmentados.
Muitas vezes, as pessoas percebem que a reconstrução de um índice corrigia um problema de desempenho. A reconstrução de um índice também cria novas estatísticas. Pode ser que a correção real seja uma nova estatística, não reconstruindo o índice.
UPDATE STATISTICS...WITH FULLSCAN
pode ser uma maneira mais barata, rápida e menos invasiva de resolver o mesmo problema de desempenho.Se você não está tendo problemas causados pela fragmentação, pode estar gastando tempo e esforço significativos sem obter ganhos reais.
Segundo, existem dois tipos de fragmentação:
Fragmentação física. É nisso que a maioria das pessoas pensa quando pensa em fragmentação. As páginas estão com defeito e precisam ser reordenadas. Ao digitalizar um índice, esse tipo de fragmentação pode às vezes ser um problema. Eu geralmente notei que isso tem o maior impacto no desempenho com leituras físicas . Se você estiver vendo os resultados
sys.dm_db_index_physical_stats
, esse número é aavg_fragmentation_in_percent
coluna.Fragmentação de baixa densidade. Essa fragmentação é causada por páginas preenchidas apenas parcialmente com dados. Você tem baixa densidade de dados porque seus dados estão espalhados por mais páginas do que o necessário. Como resultado, a leitura dos dados requer mais pedidos de veiculação porque os dados estão espalhados por mais páginas do que o necessário. Isso pode afetar as leituras lógicas e físicas. Se você estiver vendo os resultados
sys.dm_db_index_physical_stats
, esse número é aavg_page_space_used_in_percent
coluna. Esta coluna é preenchida apenas ao usar o modoSAMPLED
ouDETAILED
.Então o que fazer sobre isso:
Fragmentação física : se você está simplesmente buscando números altos
avg_fragmentation_in_percent
, considere realmente se está desperdiçando seu tempo. Verifique se você possui uma consulta real com desempenho ruim e use um ambiente de teste para confirmar que está corrigindo um problema eliminando a fragmentação.Você pode resolver a fragmentação física fazendo
ALTER INDEX...REORGANIZE
. AREORGANIZE
operação está online, movendo as páginas uma por vez para reorganizá-las novamente em ordem física. Se você interromper umaREORGANIZE
instrução no meio do processo, qualquer trabalho que já tenha sido executado será mantido - apenas a página que está sendo movida no momento será revertida. Fazer umaREORGANIZE
tabela grande e altamente fragmentada pode exigir mais espaço total no log de transações e, no modo de recuperação total, pode gerar uma quantidade significativa de backups do log de transações. Também pode levar mais tempo paraREORGANIZE
um índice altamente fragmentado do que paraREBUILD
ele.Você verá conselhos para executar
REBUILD
índices altamente fragmentados em vez deREORGANIZE
- Isso ocorre porque a reconstrução do zero pode ser mais eficiente. No entanto, a reorganização pode ser uma operação "mais on-line" e, às vezes, é preferível, mesmo para índices altamente fragmentados.A fragmentação de baixa densidade não pode ser corrigida por
REORGANIZE
. Só pode ser corrigido fazendo umALTER INDEX...REBUILD
. Fazendo o índice comONLINE=ON
, você deve minimizar o bloqueio. No entanto,REBUILD
ainda é necessário bloquear por um momento para trocar o índice antigo pelo novo índice. Em um sistema muito ocupado, atingir esse bloqueio exclusivo pode às vezes ser um problema. Você deve poder confirmar se está tendo esse problema usando algo como sp_whoisactive para examinar o bloqueio durante sua reconstrução e observando os detalhes dos bloqueios e esperas. O uso daWAIT_AT_LOW_PRIORITY
opção pode ser útil se você souber que há um próximo período de baixa utilização e sua reconstrução pode "se infiltrar" nessa troca quando a atividade cair suficientemente baixa para atingir esse bloqueio. Observe que uma longa duraçãoREBUILD
A operação também será uma transação aberta de longa duração. As transações abertas de longa execução podem ter seus próprios problemas, relacionados ao uso / reutilização do log de transações. Se você estiver usando o espelhamento ou os Grupos de disponibilidade, também haverá considerações para refazer o log de transações na réplica secundária.fonte
REORGANIZE
. No BOL : "A reorganização também compacta as páginas de índice". Bem, desde que o FILLFACTOR atual do índice permita a densidade que você procura.Aviso prévio
Após este comentário:
... Vejo como essa abordagem não funcionará.
Deixarei essa resposta como um exemplo do que não fazer.
Se você tiver mais de 200 GB livres disponíveis no banco de dados do Azure, poderá se infiltrar com a "reconstrução", copiando seus dados para uma tabela totalmente nova e solicitando-a lá.
Tentar:
LiveTable
em um vazioNewTable
LiveTable
para oNewTable
LiveTable
paraOldTable
NewTable
paraLiveTable
Obviamente, use o nome da sua tabela em vez de
LiveTable
.fonte
Idealmente, se um índice for bem projetado, não precisaremos mexer no mecanismo de bloqueio.
Parece-me que você precisará aceitar o bloqueio para desfragmentar o índice em cluster. Se houver uma boa chance de isso acontecer novamente, tente redesenhar o índice em cluster (ele deve ser estreito, exclusivo, estático e sempre crescente).
Não tenho certeza de qual versão do SQL Server você está usando, mas tente o seguinte em 2012:
SET DEADLOCK_PRIORITY LOW
- Isso informa ao mecanismo que a reconstrução do índice deve ser a vítima do impasse quando / se ocorrer um.MaxDOP = 1
- O valor MaxDOP limita o número total de CPUs lógicas usadas em paralelo para criar o índice (2005 em diante - somente na edição Enterprise).Você também pode alterar a configuração de bloqueios de página / linha, mas eu não faria isso sem testar. Você pode apenas piorar o bloqueio, especialmente se for um índice mal projetado.
A partir de 2014, existe a seguinte opção que basicamente diz ao mecanismo para permitir que outras sessões prossigam e a operação de índice online aguarde:
fonte
Eu usei a mesma abordagem que o Oreo descrita acima com grande sucesso! A única coisa que falta é que você precisa executar um script de atualização depois de copiar os dados e fazer a última renomeação.
A atualização ficará assim:
Se Key for uma coluna Identity, você precisará usar uma abordagem ligeiramente diferente.
fonte
Tente usar o sharding para distribuir dados geograficamente do seu banco de dados. Você poderá identificar diferentes janelas de manutenção para cada localização geográfica, e o tempo para fazer a manutenção será menor. Isso também irá melhorar o desempenho. Você pode aprender mais sobre este artigo. Não espere o banco de dados aumentar.
Com grandes bancos de dados e usuários conectados 24 x 7, é necessário usar a reorganização do índice e atualizar apenas as estatísticas que precisam ser atualizadas (sp_updatestats) para minimizar o tempo necessário para a manutenção e o impacto para os usuários.
Espero que isto ajude.
fonte