Eu tenho uma tabela com 1,4 bilhão de registros. A estrutura da tabela é a seguinte:
CREATE TABLE text_page (
text VARCHAR(255),
page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii
O requisito é criar um índice sobre a coluna text
.
O tamanho da tabela é de cerca de 34G.
Eu tentei criar o índice pela seguinte instrução:
ALTER TABLE text_page ADD KEY ix_text (text)
Após 10 horas de espera, finalmente desisto dessa abordagem.
Existe alguma solução viável para esse problema?
UPDATE : é improvável que a tabela seja atualizada, inserida ou excluída. A razão pela qual criar um índice na coluna text
é porque esse tipo de consulta sql seria frequentemente executado:
SELECT page_id FROM text_page WHERE text = ?
ATUALIZAÇÃO : Eu resolvi o problema particionando a tabela.
A tabela é dividida em 40 partes na coluna text
. A criação do índice na tabela leva cerca de 1 hora para ser concluída.
Parece que a criação do índice MySQL se torna muito lenta quando o tamanho da tabela se torna muito grande. E o particionamento reduz a tabela em troncos menores.
CREATE INDEX
declaração normal ?Respostas:
Poderia ser o seu sistema simplesmente não está à altura da tarefa? Eu não uso o MySQL (SQL Server aqui), mas conheço a dificuldade de indexar uma tabela de entrada de 800 milhões. Basicamente .... você precisa do hardware certo para isso (como em: muitos discos rápidos). Agora uso quase uma dúzia de Velociraptors e o desempenho é ótimo;)
Servidores SQL (não como o MS SQL Server, mas como servidores de banco de dados usando SQL) vivem e morrem com acesso a discos, e discos normais simplesmente não estão à altura da tarefa de operações maiores.
fonte
Você pode criar um índice nos primeiros (por exemplo, 10) caracteres do campo de texto.
Dos documentos:
É possível criar índices que usam apenas a parte inicial dos valores da coluna, usando a sintaxe col_name (length) para especificar um comprimento de prefixo de índice:
fonte
Eu resolvi o problema particionando a tabela.
A tabela é dividida em 40 partes na coluna
text
. A criação do índice na tabela leva cerca de 1 hora para ser concluída.Parece que a criação do índice MySQL se torna muito lenta quando o tamanho da tabela se torna muito grande. E o particionamento reduz a tabela em troncos menores.
fonte
Defina o sort_buffer_size como 4 GB (ou o quanto você puder, dependendo da quantidade de memória que você possui).
No momento, o índice de criação está fazendo uma classificação, mas como você tem um tamanho de sort_buffer_size de 32 MB, basicamente está debulhando o disco rígido desnecessariamente.
fonte
Se você não precisar fazer consultas como:
Eu sugeriria criar uma nova coluna de hash e indexar a tabela pela coluna. O tamanho geral da tabela + índice pode ser muito menor.
UPD : A propósito, 1,4 bilhão de números inteiros de chave primária ocupam cerca de 6 GB, ou seja, o comprimento médio da string é inferior a 30 caracteres; a indexação em um prefixo pode ser mais preferível.
Você também deve dar uma olhada no mecanismo de armazenamento MERGE .
fonte
Uma maneira de fazer isso é criar uma nova tabela com o conjunto de índices e copiar os dados para a nova tabela.
Além disso, verifique se você tem espaço temporário suficiente.
fonte
Caso você ainda esteja se perguntando como fazer isso da melhor maneira, sugiro que você use uma ferramenta de alteração de tabela on-line.
Existem muitos deles na internet, um dos famosos é:
http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
Temos os mesmos problemas com grandes tabelas (mais de 500mil registros) e a alteração é perfeita. Ele cria uma nova tabela tmp, adiciona gatilho à tabela original (para os novos registros de atualização / exclusão / inserção) e, enquanto isso, copia todos os registros para a nova tabela (com a nova estrutura)
Boa sorte!
fonte