Como otimizar tabelas InnoDB no MySQL

8

Eu tenho pesquisado como otimizar apenas tabelas fragmentadas no MySQL e revi este post sobre otimização de tabelas . Basicamente, ele executa uma consulta no banco de dados information_schema para qualquer tabela data_free > 0e cria uma instrução SQL OPTIMIZEapenas para essas tabelas. Fiz essa consulta e ele identificou 148 tabelas para otimização. Todas as tabelas identificadas são tabelas do InnoDB. Após executar o script SQL de otimização resultante, executei novamente o script original para identificar tabelas fragmentadas e ele retornou exatamente as mesmas tabelas durante a primeira passagem.

Vi posts conflitantes sobre as tabelas do InnoDB e o OPTIMIZEcomando. Alguns dizem que OPTIMIZEnão funcionará com tabelas do InnoDB e que você precisa executar ALTER TABLE table_name ENGINE=INNODB. Outros dizem que, OPTIMIZEna verdade, chama o ALTER TABLEcomando ao executar nas tabelas do InnoDB. Com isso em mente, executei o ALTER TABLEcomando em uma das tabelas do InnoDB identificadas como fragmentadas ( data_free > 0) e descobri que data_freeelas não foram alteradas posteriormente. Ainda é maior que 0. Também reiniciei o MySQL e verifiquei apenas para encontrar os mesmos resultados.

Agora, temos vários servidores executando o MySQL 5.5.29 em nossa organização e executei uma consulta em todos eles para identificar quaisquer tabelas do InnoDB DATA_FREE=0 or NULLe nenhuma foi retornada. Eles são todos maiores que zero.

Também executei o OPTIMIZEcomando em algumas MyISAMtabelas onde DATA_FREEera maior que zero e verifiquei que era zero depois.

Alguém pode lançar alguma luz sobre isso para mim? Qual é o método adequado para remover a fragmentação das tabelas do InnoDB? Qual é o método adequado para determinar tabelas InnoDB fragmentadas?

obrigado

user3151788
fonte

Respostas:

9

Suponho que você esteja usando innodb_file_per_tableesta resposta.

Há mais de um significado para "Fragmentação InnoDB":

  1. .ibd o arquivo está fragmentado e é muito grande, enquanto o conjunto de dados é pequeno
  2. As páginas de índice são fragmentadas, pois há muitas páginas para conter poucos dados; nesse caso, elas podem ser mescladas.

Por favor, considere este post que escrevi há algum tempo: mostra como, após limpar muitas linhas de uma tabela grande, o arquivo de dados é fragmentado (ou seja, é muito grande no sistema de arquivos - é um problema conhecido que esses arquivos nunca diminuem de tamanho). E, no entanto, os índices não foram fragmentados no final da exclusão: isso ocorre porque o InnoDB mescla corretamente as páginas quando elas ficam vazias (er).

O OPTIMIZEcomando realmente não se aplica ao InnoDB. O que ele faz é reconstruir a tabela (exatamente como um ALTER). Veja isso:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Quanto a DATA_FREE: sugiro que você simplesmente ignore essa variável. Para ser sincero, trabalho com tabelas do InnoDB há 10anos e nunca achei esse valor muito consistente com nada.

E agora é hora da discussão real: o que exatamente você está tentando alcançar? A menos que seu banco de dados esteja completamente obsoleto, sempre haverá alguma fragmentação. É natural o processo de adicionar, remover e atualizar linhas na sua tabela.

A fragmentação não é tão má: o espaço livre pode ser recuperado por novos dados. Se suas tabelas não são muito grandes, esqueça a coisa toda. Para tabelas muito grandes, você pode ganhar algum espaço em disco otimizando a tabela. Mas pergunte-se: em quanto tempo a tabela alcançaria a mesma fragmentação? Uma hora? Um dia? Uma semana? IMHO em todos esses casos, é inútil otimizar a tabela.

No entanto, se uma tabela grande é massivamente eliminada de dados, o que não se espera que retorne, sou a favor de otimizá-la. Digamos que você saiba que possui alguns dados redundantes, que consistem em cerca de 30% do tamanho da sua tabela. Claro, seria ótimo ter esse espaço em disco de volta.

Conclusão: considere apenas esses problemas com tabelas muito grandes; somente se você tiver problemas com espaço em disco.

Shlomi Noach
fonte
Concordo que o data_free não é útil. Ele só conta espaço em "extensões livres" para o espaço de tabela, que é uma métrica terrível para calcular a fragmentação. Acho que se você não estiver usando innodb_file_per_table, também mostrará o mesmo valor para todas as tabelas no espaço de tabela compartilhado.
Jeremycole