Fragmentação do índice torna as consultas muito mais lentas porque a ordem física das páginas de índice difere da ordem lógica, o que aumenta os tempos de E/S, CPU e espera. Neste guia, mostrarei como Reorganização, A reconstrução, o fator de preenchimento e a monitorização trabalham em conjunto para reconhecer de forma fiável e eliminar de forma sustentável a fragmentação.
Pontos centrais
- Definição deÁrvores B* fragmentadas geram mais E/S e varreduras mais lentas.
- CausasDivisões de páginas, eliminações, valores chave deslocados.
- LimiaresReorganização de ~5-30 %, reconstrução de ~30 %.
- Foco no MySQLOTIMIZAR TABELA e factores de preenchimento.
- AutomatizaçãoTrabalhos programados, operações em linha, métricas.
O que significa tecnicamente a fragmentação do índice?
Chamo-lhe Fragmentação a discrepância entre a sequência de chaves lógicas e a cadeia de páginas físicas de um índice de árvore B*. Muitos INSERTs, UPDATEs e DELETEs resultam em lacunas, divisões e páginas de folhas desordenadas, o que desencadeia mais operações de leitura. O resultado: as varreduras saltam com mais frequência, os acessos ao cache do buffer diminuem e os custos da CPU aumentam. Mesmo os planos ideais sofrem porque a memória entrega as páginas dispersas mais lentamente. Portanto, eu sempre presto atenção ao contexto de carga de trabalho, tamanho dos dados e disposição da memória.
Tipos de fragmentação e respectivos sintomas
Faço uma distinção pragmática:
- Fragmentação lógicaAs folhas de página já não são concatenadas na sequência de chaves. As varreduras de intervalo requerem saltos adicionais, a leitura antecipada é menos eficaz.
- Fragmentação internaAs páginas têm muito espaço não utilizado (níveis de preenchimento baixos). Têm de ser lidas mais páginas por linha de resultado; o tamanho do índice aumenta sem benefício.
- Fragmentação estruturalAltura desfavorável da árvore, nós desequilibrados ou pilhas com registos reencaminhados (por exemplo, no SQL Server). Os acessos tornam-se mais indirectos.
Isso pode ser medido como mais páginas lidas por linha, latências mais altas durante varreduras de intervalo ou por ordem e uma taxa de acerto de cache em queda. Eu sempre correlaciono os sinais com estatísticas de espera para evitar confusão com problemas de rede ou armazenamento.
Causas: Inserções, actualizações, divisões de páginas
As inserções frequentes enchem as páginas até ao limite, depois uma nova chave obriga a uma Divisão de páginas, que deixa duas páginas meio preenchidas. As eliminações removem registos, mas o espaço livre permanece distribuído e nem sempre é utilizado localmente com a inserção seguinte. As actualizações que alteram colunas-chave movem registos e criam mais lacunas. Os padrões de chave aleatórios, como os GUID, aumentam ainda mais a dispersão e, consequentemente, a confusão. Minimizo as divisões utilizando a função Fator de enchimento para corresponder à carga de escrita.
Tornar as perdas de desempenho mensuráveis
Não meço a fragmentação isoladamente, mas em combinação com os tempos de consulta, leituras de registos, leituras de páginas e classes de espera. Se a latência média das varreduras de intervalos aumentar e a CPU por consulta aumentar, verifico primeiro os índices físicos dos índices. A elevada fragmentação aumenta o número de páginas lidas por igual número de linhas e comprime os tempos de espera para E/S. Uma comparação bem fundamentada antes e depois da reorganização ou reconstrução mostra o benefício real. Para obter informações básicas sobre bloqueio, planos e estrangulamentos, vale a pena consultar Desempenho da base de dados, para classificar corretamente os sintomas.
Métricas, esperas e eficiência da página em pormenor
Na prática, também observo:
- Páginas por digitalizaçãoQuantas páginas de folhas são lidas numa área de digitalização típica? Se o valor aumentar com a mesma quantidade de resultados, isso indica fragmentação ou níveis de preenchimento demasiado baixos.
- Acerto de leitura antecipadaAs cadeias fragmentadas sabotam os prefetches sequenciais; o efeito é menor nos SSDs, mas não nulo, uma vez que a CPU, os latches e a cache continuam a sofrer.
- Classes em esperaPAGEIOLATCH/IO-Waits (SQL Server), leitura sequencial/espalhada do ficheiro db (Oracle) ou aumento das latências de leitura InnoDB (MySQL) aumentam com saltos mais fortes no índice.
- Qualidade da cacheSe a taxa de acerto do buffer pool cair em paralelo com a fragmentação, uma reconstrução quase sempre vale a pena - especialmente para varreduras de grandes intervalos.
Analisar a fragmentação: SQL Server, MySQL, Oracle
Começo sempre a análise com um Instantâneo de saúde do índice e filtrar pequenos índices cuja utilização de páginas flutua estatisticamente. No SQL Server, o sys.dm_db_index_physical_stats fornece o grau de fragmentação juntamente com o page_count, para que eu possa ponderar os valores anómalos. Valores superiores a 5-30 % indicam reorganização, valores anómalos superiores a 30 % indicam uma reconstrução, especialmente com um número de páginas elevado. No MySQL, verifico as vistas SHOW TABLE STATUS ou INFORMATION_SCHEMA e observo os dados e o comprimento do índice ao longo do tempo. No Oracle, também verifico se está disponível uma reconstrução em linha para Tempo de inatividade a evitar.
Consultas práticas e ponderação
Trabalho com consultas simples e reutilizáveis e estabeleço prioridades de acordo com o tamanho e a relevância da página:
- Servidor SQLDetermino a fragmentação e filtro os índices pequenos.
SELECT DB_NAME() AS db, OBJECT_NAME(i.object_id) AS obj, i.name AS idx, ips.index_type_desc, ips.page_count, ips.avg_fragmentation_in_percent FROM sys.indexes i CROSS APPLY sys.dm_db_index_physical_stats(DB_ID(), i.object_id, i.index_id, NULL, 'SAMPLED') ips WHERE ips.page_count >= 100 ORDER BY ips.avg_fragmentation_in_percent DESC, ips.page_count DESC; - MySQL (InnoDB)Analiso o tamanho do índice, o espaço livre e a taxa de variação.
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, INDEX_LENGTH, DATA_FREE FROM information_schema.TABLES WHERE ENGINE = 'InnoDB' E INDEX_LENGTH > 0 ORDER BY (DATA_FREE) DESC;Ao mesmo tempo, comparo os valores ao longo do tempo (por exemplo, diariamente) para separar as tendências reais dos valores anómalos. Para as estatísticas, utilizo o ANALYZE TABLE com moderação se o optimizador assumir cardinalidades incorrectas.
- OráculoVerifico as estatísticas dos segmentos (espaços livres, extensões) e a disponibilidade do REBUILD ONLINE para manter as janelas de manutenção previsíveis.
Para mim, é importante analisar apenas os índices com elevada utilização. Um índice fragmentado mas não utilizado tem mais probabilidades de ser um candidato à remoção do que à reorganização.
Reorganização vs. reconstrução: Matriz de decisão
Escolho o método de acordo com o grau de Fragmentação e janelas operativas, porque nem todos os ambientes conseguem lidar com picos intensivos de E/S. A reorganização reorganiza as páginas de folha, reduz os saltos lógicos, comprime para o fator de preenchimento e geralmente permanece em linha. A reconstrução reconstrói o índice, limpa-o completamente, devolve a memória e actualiza as estatísticas, mas requer CPU, E/S e, frequentemente, bloqueios mais longos. Pequenos índices com menos de aproximadamente 100 páginas raramente se beneficiam muito, enquanto grandes estruturas com fragmentação de 30 % ou mais ganham significativamente. Documentei a decisão com números-chave para que o efeito permaneça compreensível e o Calendário de manutenção adapta-se.
| Método | Necessidades de recursos | Utilização típica | Efeito principal |
|---|---|---|---|
| Reorganização | Baixo a médio | ~5-30 % Fragmentação | Reorganização, compressão do fator de preenchimento |
| Reconstruir | Elevado | > 30 % Fragmentação | Reconstrução completa, libertação de memória |
Opções online, bloqueios e efeitos secundários
Para um funcionamento com poucas interrupções, utilizo - quando disponível - Reconstruções online em. Eu presto atenção a isto:
- Edição/VersãoAs funcionalidades em linha variam consoante a base de dados e a edição. Verifico cada ambiente separadamente.
- Bloqueios temporários de metadadosMesmo o “online” requer normalmente blocos no início/fim. Programo-os deliberadamente em fases calmas.
- Temp/gamas de trabalhoOpções como SORT_IN_TEMPDB (SQL Server) reduzem a carga no ficheiro de dados principal, mas requerem espaço de armazenamento adicional.
- ReplicaçãoAs reconstruções aumentam o volume do registo. Monitorizo o atraso das réplicas e, se necessário, reduzo-o para evitar atrasos.
Para os heaps do SQL Server, tenho em conta Registos reencaminhados; Neste caso, a reconstrução de uma tabela ajuda a remover os redireccionamentos. No Oracle, utilizo o REBUILD ONLINE ou o MOVE PARTITION (com UPDATE INDEXES) para reduzir o tempo de inatividade.
Fator de preenchimento, divisão de páginas e memória
Um adequado Fator de enchimento Defino entre 70-90 % para tabelas que escrevem muito, para que as futuras inserções possam utilizar espaço livre localmente. Se baixar demasiado o fator de preenchimento, o índice cresce mais rapidamente e ocupa mais memória; se o definir demasiado alto, as divisões e a fragmentação aumentam. Assim, observo a relação entre a utilização da página, a carga de escrita e o padrão de inserção ao longo de vários ciclos. Para as reconstruções, defino deliberadamente o fator de preenchimento por índice e não de forma generalizada para toda a base de dados. O controlo regular evita que um índice inicialmente bom compromisso meses mais tarde.
Compreender os factores de preenchimento por plataforma
- Servidor SQLFILLFACTOR é uma propriedade do índice que tem efeito durante a reconstrução/criação. Eu defino um valor mais baixo para índices secundários muito voláteis e um valor mais alto para estruturas de leitura pesada. Eu documento o valor selecionado por índice e recalibro-o após as alterações do perfil de carga.
- MySQL (InnoDB)Com innodb_fill_factor Influencio o espaço livre que o InnoDB deixa para (re)construções. Não se aplica ao DML quotidiano, mas com OPTIMIZE/ALTER ajuda a reduzir as divisões no futuro. Também planeio os hotspots (chaves monótonas) de forma a reduzir a concorrência de latches e as divisões.
- Oracle e PostgreSQLparâmetro STORAGE ou. FATOR DE ENCHIMENTO (Postgres) dão espaço para o ar livre nas páginas. Para tabelas de escrita pesada, utilizo níveis de preenchimento conservadores e equilibro a memória extra com tempos de pesquisa mensuravelmente melhores.
Específico para MySQL e WordPress
No MySQL ajuda-me OPTIMIZE TABLE no InnoDB para reorganizar tabelas e índices associados e devolver espaço livre. Cargas de trabalho altamente fragmentadas com muitas exclusões também se beneficiam da criação periódica de índices secundários críticos. Nas instalações do WordPress, reduzo a desordem, como revisões e comentários de spam, antes de otimizar para que menos páginas tenham de ser reordenadas. Combino essas etapas com uma estratégia de índice limpo para wp_postmeta e tabelas semelhantes que frequentemente acionam varreduras. Uma introdução prática pode ser encontrada no guia para Otimizar os índices do WordPress, que aborda os obstáculos típicos.
Prática de MySQL: OPTIMIZE, partições e efeitos secundários
Também presto atenção ao InnoDB:
- OTIMIZAR TABELA reconstrói a tabela (e os índices) e pode ser executado em grande parte “no local”, dependendo da versão, mas requer sempre meta-bloqueios e espaço livre no registo. Estou a planear janelas de tempo dedicadas a isto.
- Partição permite uma manutenção direcionada: OPTIMIZAR PARTIÇÃO apenas para áreas quentes ou muito apagadas reduz os picos de E/S e o tempo de execução.
- ReplicaçãoAs grandes reconstruções geram volume de binlog e podem atrasar as réplicas. Distribuo a manutenção por várias noites ou trabalho em partições.
- ANALISAR TABELA renova as estatísticas de que o optimizador necessita para melhorar os seus planos - especialmente após grandes alterações estruturais.
Em ambientes WordPress, reduzo antecipadamente transientes, revisões e mensagens eliminadas para que o OPTIMIZE mova menos dados. No caso do wp_postmeta, verifico se as consultas são executadas especificamente através de índices compostos adequados, de modo a evitar pesquisas alargadas.
Resumo das especificidades do PostgreSQL
Embora o foco aqui seja o MySQL, tenho em conta os ambientes heterogéneos:
- VÁCUO/Autovácuo evita o inchaço, mas não substitui o REINDEX se as estruturas da árvore B estiverem muito fragmentadas.
- REINDEXAR EM SIMULTÂNEO permite a criação de novos índices em grande parte em linha, com um bloqueio limitado.
- fator de enchimento por tabela/índice controla o ar livre para futuras INSERÇÕES/ACTUALIZAÇÕES. As tabelas com muita escrita beneficiam de valores mais baixos.
- Divisórias por período, aliviar as janelas de manutenção; o REINDEX pode ser utilizado especificamente para cada partição.
Manutenção automatizada e valores-limite
Automatizo a reorganização e a reconstrução utilizando o robusto Limiares e apenas ativar os índices com um número de páginas suficiente para evitar ruídos. Os trabalhos são executados em janelas de manutenção, enquanto eu executo operações longas através de opções online com o menor tempo de inatividade possível. Uma abordagem escalonada adia as grandes reconstruções para períodos calmos e executa pequenas reformulações com mais frequência. Actualizo as estatísticas após grandes alterações, para que o optimizador selecione prontamente os melhores planos. Os alertas são acionados assim que a fragmentação ou as latências excedem os limites predefinidos, para que eu possa agir antes que os utilizadores se queixem.
Runbook: Sequência de passos para resultados sustentáveis
- IdentificarInstantâneo dos N índices principais por tamanho e fragmentação, filtrar índices pequenos.
- Estabelecer prioridadesOrdenar por criticidade da carga de trabalho, contagem de páginas e carga de digitalização.
- PlaneamentoPrograme a reposição/reconstrução de acordo com os valores limite, calcule as opções em linha e os requisitos de temperatura/registo.
- ExecutarEscalonamento de objectos de grandes dimensões, limitação de E/S, monitorização de atrasos de replicação.
- EstatísticasAtualizar as estatísticas após a reconstrução/OPTIMIZE (ou assegurar que isto é feito automaticamente).
- ValidarMedir antes/depois: Latência, páginas lidas, tempos de espera, taxa de acerto da cache.
- CalibrarVerificar os factores de preenchimento e os limiares, documentar as lições aprendidas.
Afinação do alojamento: Regras práticas
Nos ambientes de alojamento, planeio análises semanal, regulam a janela de E/S da manutenção e combinam-se com o armazenamento em cache para manter os hotsets em memória. Os parâmetros TempDB/redo/binlog e os suportes de armazenamento influenciam significativamente os efeitos percebidos da desfragmentação. Também avalio se os índices supérfluos apenas geram custos, porque cada índice adicional aumenta o trabalho de escrita e as hipóteses de fragmentação. Antes de cada novo índice, verifico os padrões de carga de trabalho, as cardinalidades e a cobertura existente. Nesta visão geral, descrevo os obstáculos típicos Armadilhas de índice no MySQL, o que evita erros de avaliação.
Custos/benefícios e quando não faço nada conscientemente
Nem toda a fragmentação vale a pena manter. Eu dispenso-a deliberadamente quando:
- O objeto é pequeno (por exemplo, menos de 100 páginas) e que flutua muito - é aqui que as vantagens não se concretizam.
- As consultas são selectivas (principalmente pesquisas por chave) e não estão a ser executadas análises de intervalos.
- A carga de trabalho é transitória (janela de migração, arquivamento em breve) - então só planeio uma reconstrução final.
Em vez disso, invisto em melhores índices, menos redundância e uma seleção de chaves limpa para que as futuras divisões ocorram com menos frequência.
Quando reorganizar, quando esperar?
Estou a lançar um Reorganização se o grau de fragmentação aumentar moderadamente e se forem afectadas páginas suficientes para ter um efeito real. Após eliminações em massa ou arquivamento, uma redistribuição ordenada traz muitas vezes ganhos de digitalização assinaláveis. No caso de anomalias graves ou requisitos de armazenamento, planeio uma reconstrução, de preferência em linha, para minimizar a perturbação das operações. Muitas vezes, não mexo em índices pequenos, com menos de 100 páginas, porque a sua disposição varia muito e os benefícios são mínimos. Documentei a decisão, juntamente com os valores antes/depois, para que seja mais fácil planear os ciclos futuros.
Prevenção a longo prazo através da conceção
Bom Conceção do esquema reduz a fragmentação mesmo antes da primeira inserção, assegurando que a seleção de chaves, os tipos de dados e a normalização são consistentes. Evito linhas muito largas, que permitem menos registos de dados por página e favorecem as divisões. O particionamento separa os dados frios dos quentes e reduz os efeitos secundários durante a manutenção e as cópias de segurança. A otimização cuidadosa das consultas reduz a dependência de pesquisas dispendiosas e alinha os índices com os padrões do mundo real. À medida que as cargas de trabalho mudam, ajusto as definições dos índices de forma incremental, em vez de descartar estruturas inteiras ad hoc.
Seleção de chave e padrão de inserção
A escolha da chave primária tem uma influência decisiva no comportamento da divisão:
- Teclas monótonas (por exemplo, AUTO_INCREMENT, IDs baseados no tempo) agrupam as inserções na borda direita, reduzem a dispersão e as divisões, mas podem criar hotspots. Equalizo os hotspots com buffering/batching.
- Chaves aleatórias (por exemplo, GUID/UUID v4) distribuem a carga, mas aumentam a probabilidade de divisão. As variantes sequenciais (por exemplo, UUIDs baseados no tempo) equilibram melhor a distribuição e a ordem.
- Tecla larga aumentam o índice e o número de páginas necessárias. As chaves enxutas e selectivas são mais sustentáveis.
Além disso, a compressão de linhas e páginas reduz a taxa de divisão porque há espaço para mais entradas por página. No entanto, verifico sempre os custos da CPU e a disponibilidade de licenças/funcionalidades antes de ativar a compressão.
Brevemente resumido: Passos com efeito
Começo com uma Análise dos índices maiores e mais fragmentados, estabelecer prioridades de acordo com o número de páginas e a criticidade da carga de trabalho. Em seguida, aplico medidas escalonadas: reorganizar os casos moderados, reconstruir os casos pesados, reajustar os factores de preenchimento para cada índice. Os trabalhos automatizados mantêm a ordem sem intervenção manual constante, enquanto os alertas são acionados de forma fiável em caso de anomalias. Os ambientes MySQL e WordPress beneficiam visivelmente se eu reduzir antecipadamente o desperdício de dados e mantiver apenas os índices úteis. Com monitorização consistente, limites claros e manuais repetíveis Desempenho estável - mesmo quando os dados estão a crescer rapidamente.


