As DISABLE KEYS do MySqlDump não têm efeito na importação

10

Tenho um acompanhamento da minha pergunta anterior sobre velocidade de importação com o Inno-Tables (surpresa!).

Cenário
Tento importar algum grande * despejo de banco de dados na minha máquina de desenvolvimento local em tempo razoável. Temos muitos KEYs anexados às tabelas que acabaram sendo um gargalo, mas ainda são importantes para o nosso sistema ativo.

Minha abordagem depois de fazer a pergunta acima foi excluir KEY ...instruções do dump, importar e adicionar novamente chaves.

No entanto, muitas vezes me vejo editando um despejo atual para importá-lo localmente e me deparei com esses "comentários" engraçados (as disable/enable keyslinhas)

--
-- Dumping data for table `monster`
--

LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT  INSERT  INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;

Mas, na verdade, esses "comentários" são condicionais MySql-Statements

Isso foi novidade para mim, mas ok, dado o formulário de saída, mysql --versiontudo parece bem para mim: mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3

O que eu assumo
A mesa está trancada (tudo bem, sou só eu no dev mashine). Em seguida, as chaves definidas no esquema da tabela são desativadas, os dados são importados, as chaves são ativadas.
Portanto, durante a fase de "inserção de dados", não deve haver desperdício de tempo nas chaves, mas sim examinadas após a inserção de todos os dados.

Eu estaria pensando que esse é o mesmo comportamento como se eu KEY 'foo' (foo)'excluísse todas as linhas do despejo, importe o despejo e execute um script ADD KEY 'foo' ...posteriormente.

O que eu observo
É muito mais rápido excluir manualmente as chaves, importar e adicionar novamente chaves, depois confiar em DISABLE KEYSinstruções condicionais criadas por mim.mysqldump

Edição manual de dump + importação do mysql + adição de chaves = 15 + 8 + 8 ≈ 30min
Importação simples do mysql: desistiu (estou apenas sendo pago por 8 horas / dia> :))

Não posso deixar de pensar que estou perdendo algo muito fundamental aqui (ou o banco de dados está me vasculhando).

nuala
fonte
2
Curto prazo: use mysqldump --innodb-optimize-keysdo Percona percona.com/doc/percona-server/5.5/management/… Longo prazo: pare de usar o mysqldump e use mydumper ou xtrabackup.
jynus

Respostas:

12

Você não pode confiar no InnoDB DISABLE KEYS;e ENABLE KEYS;para ele porque não está implementado no InnoDB Storage Engine. Correndo ALTER TABLE ... DISABLE KEYS;e ALTER TABLE ... ENABLE KEYS;foram projetados para o MyISAM. Como diz a documentaçãoALTER TABLE do MySQL para :

Se você usar ALTER TABLE em uma tabela MyISAM, todos os índices não exclusivos serão criados em um lote separado (como para REPAIR TABLE). Isso deve tornar o ALTER TABLE muito mais rápido quando você tiver muitos índices.

Para tabelas MyISAM, a atualização de chaves pode ser controlada explicitamente. Use ALTER TABLE ... DISABLE KEYS para dizer ao MySQL para parar de atualizar índices não únicos. Em seguida, use ALTER TABLE ... ENABLE KEYS para recriar índices ausentes. O MyISAM faz isso com um algoritmo especial que é muito mais rápido do que inserir chaves uma a uma, portanto, desativar as chaves antes de executar operações de inserção em massa deve proporcionar uma considerável aceleração. O uso de ALTER TABLE ... DISABLE KEYS requer o privilégio INDEX, além dos privilégios mencionados anteriormente.

Enquanto os índices não únicos estão desativados, eles são ignorados para instruções como SELECT e EXPLAIN que, de outra forma, os usariam.

Nenhuma menção é feita ao InnoDB no contexto de ALTER TABLE ... DISABLE/ENABLE KEYS;

Mesmo que você execute ALTER TABLE ... DISABLE KEYS;uma tabela InnoDB, ela gera um aviso:

mysql> show create table mytimes\G
*************************** 1. row ***************************
       Table: mytimes
Create Table: CREATE TABLE `mytimes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `totalTime` int(11) NOT NULL,
  `totalTimeDesc` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

É por isso que não há efeito. Lembre-se de que @jynus mencionou a mesma coisa em sua resposta no ponto 7 .

Lembre-se também de que o MyISAM mantém dados e índices em dois arquivos separados (.MYD para dados, .MYI para índices); portanto, seria trivial desativar e ativar índices. O InnoDB mantém a PRIMARY KEY e a linha de dados nas mesmas páginas do InnoDB (por meio do Índice de Cluster). Os índices secundários levarão a PRIMARY KEY como um anexo para cada entrada secundária da folha do índice . Uma vez que os dados e índices estão interligados por meio do índice de cluster, ninguém, até o momento, tentou implementar DISABLE KEYSe ENABLE KEYSno InnoDB.

RolandoMySQLDBA
fonte
11
"Eu te disse" :-)
jynus 15/09/14
@jynus HA HA :-). Você deve postar seu comentário do mysqldump no InnoDB ( dba.stackexchange.com/questions/76565/… ) como resposta.
RolandoMySQLDBA 15/09
@ yoshi Estou escrevendo um artigo com base na sua pergunta original, fique atento.
jynus
@yosi Conforme prometido: dbahire.com/…
jynus
@RolandoMySQLDBA, se o InnoDB não puder ativar / desativar chaves, ele não deve dar um erro em vez de um mero aviso?
Pacerier 23/02