Na minha inscrição, meus INSERTs parecem estar demorando uma grande parte do tempo. Eu tenho um grande número de objetos na memória (~ 40-50.000) que eu quero inserir em uma tabela.
Vamos pegar uma tabela de amostra
CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB
Tomando 3 linhas como meu tamanho de lote, a seguir estão as abordagens que eu poderia pensar para inserir
Abordagem 1 - construir e acionar 3 inserções brutas
INSERT INTO bill (amount, bill_date) VALUES (10, '2012-01-01 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (20, '2012-01-02 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (40, '2013-02-05 00:00:00');
Abordagem 2 - agrupar os valores em uma consulta
INSERT INTO bill (amount, bill_date) VALUES
(10, '2012-01-01 00:00:00'),
(20, '2012-01-02 00:00:00'),
(40, '2013-02-05 00:00:00');
Abordagem 3 - dispare esta consulta 1 vez passando 6 parâmetros
INSERT INTO bill (amount, bill_date) VALUES
(?, ?), (?, ?), (?, ?);
Abordagem 4 - Dispare esta consulta preparada 3 vezes, alterando os 2 parâmetros a cada vez
INSERT INTO bill (amount, bill_date) VALUES (?, ?);
Quaisquer outras abordagens são bem-vindas.
Minha pergunta é
Qual é a maneira mais rápida de fazer várias inserções em uma tabela?
Eu li este link no mysql insert speed e este guia para programação JDBC , mas não consigo chegar a uma conclusão.
O meu caso -
Atualmente, minha tabela possui ~ 20 colunas, a maioria delas números, com algumas varchar (60) e 1 coluna de texto. Mysql versão 5.5. Executando no INNODB e possui 1 índice nas chaves primárias Inteiras. Todas as consultas são executadas na transação.
Eu construo minhas consultas a partir de Java e uso o Spring JDBC para executar as consultas.
Atualmente, estou seguindo a Abordagem 3, que leva cerca de 10 segundos para 20.000 inserções em uma tabela vazia, sem incluir o tempo necessário para construir a consulta.
Para manter as coisas em perspectiva, são necessários 100-200 milis para buscar os dados da tabela.
Há algo que estou perdendo? Como faço para tornar as pastilhas mais rápidas?
Respostas:
Considere agrupar seus commits. Um tamanho de lote de 1024 é um bom tamanho inicial. Altere os tamanhos dos lotes até atingir o rendimento ideal.
fonte
Você testou ou seria possível descartar índices na (s) tabela (s) de banco de dados de destino em que está inserindo, insira-os em blocos em lotes menores (ideal como indicado acima) e, em seguida, reconstrua os índices nas tabelas de destino quando todas as inserções estiverem concluídas? Pode ser algo fácil o suficiente para testar para confirmar.
fonte
Algumas dicas de carregamento de dados em massa do documento mysql são possíveis úteis. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html
Você pode aumentar a velocidade da pastilha de algumas maneiras:
Espero que esta ajuda!
fonte