Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Tabela com 80 milhões de registros e adicionar um índice leva mais de 18 horas (ou para sempre)! O que agora?


Ok, acontece que esse problema foi mais do que apenas criar uma tabela, indexá-la e esquecer o problema :) Aqui está o que eu fiz caso alguém enfrente o mesmo problema (eu usei um exemplo de endereço IP, mas funciona para outros tipos de dados também):

Problema:sua tabela tem milhões de entradas e você precisa adicionar um índice muito rápido

Caso de uso: Considere armazenar milhões de endereços IP em uma tabela de pesquisa. Adicionar os endereços IP não deve ser um grande problema, mas criar um índice neles leva mais de 14 horas.

Solução :Particione sua tabela usando Partitionin do MySQL g estratégia

Caso nº 1:quando a tabela que você deseja ainda não foi criada
CREATE TABLE IPADDRESSES(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ipaddress BIGINT UNSIGNED,
  PRIMARY KEY(id, ipaddress)
) ENGINE=MYISAM
PARTITION BY HASH(ipaddress)
PARTITIONS 20;

Caso nº 2:quando a tabela que você deseja já está criada. Parece haver uma maneira de usar ALTER TABLE para fazer isso, mas ainda não descobri uma solução adequada para isso. Em vez disso, existe uma solução um pouco ineficiente:
CREATE TABLE IPADDRESSES_TEMP(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ipaddress BIGINT UNSIGNED,
  PRIMARY KEY(id)
) ENGINE=MYISAM;

Insira seus endereços IP nesta tabela. E então crie a tabela real com partições:
CREATE TABLE IPADDRESSES(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ipaddress BIGINT UNSIGNED,
  PRIMARY KEY(id, ipaddress)
) ENGINE=MYISAM
PARTITION BY HASH(ipaddress)
PARTITIONS 20;

E então finalmente
INSERT INTO IPADDRESSES(ipaddress) SELECT ipaddress FROM IPADDRESSES_TEMP;
DROP TABLE IPADDRESSES_TEMP;
ALTER TABLE IPADDRESSES ADD INDEX(ipaddress)

E pronto... a indexação na nova tabela me levou cerca de 2 horas em uma máquina de 3,2 GHz com 1 GB de RAM :) Espero ter ajudado.