Durante minha pesquisa superficial, não consegui encontrar uma resposta definitiva sobre os benefícios que ela SELECT INTO OUTFILE
oferece INSERT INTO ... SELECT
. Ao ler os documentos relacionados a INSERT INTO ... SELECT
bloqueios em tabelas InnoDB, ele declara:
define um registro de índice exclusivo sem um bloqueio de lacuna em cada linha inserida em T. Se o nível de isolamento da transação for READ COMMITTED ou innodb_locks_unsafe_for_binlog estiver ativado e o nível de isolamento da transação não for SERIALIZABLE, o InnoDB faz a pesquisa em S como uma leitura consistente (sem fechaduras). Caso contrário, o InnoDB define bloqueios de próxima chave compartilhados em linhas de S.
Para evitar o bloqueio com INSERT INTO ... SELECT
parece que devo garantir o nível READ COMMITTED
de isolamento é evitar bloqueios na tabela de origem durante a consulta.
No entanto, não consegui encontrar nenhuma resposta oficial sobre bloqueios e uso SELECT INTO OUTFILE
, nem mesmo as informações de bloqueio de referência dos documentos do MySQL.
Meu objetivo é evitar o bloqueio da tabela de origem enquanto a consulta é executada para evitar o empilhamento de conexões.
Você deve usar SELECT ... LOCK IN SHARE MODE . Por quê ?
No seu caso, você pode tentar isso
Isso faria duas
SELECT
consultasSELECT
para bloquear as linhas na tabela que você desejaSELECT
a executarSELECT ... INTO OUTFILE
Pessoalmente, não acho que você precise ser tão opressor. O isolamento da transação deve ser inteligente o suficiente para retirar esse atômico
SELECT
e usar as mesmas linhas para o arquivoINSERT
. Eu sei que disseshould be
e é por isso que você está fazendo a pergunta em primeiro lugar.Quer você faça
SELECT ... INTO OUTFILE
como um comando ou da maneira pesada que estou propondo, os dados da linha da tabela de origem serão totalmente legíveis.DE UMA CHANCE !!!
ATUALIZAÇÃO 2014-12-10 15:12 EST
Seu comentário
Eles são operacionalmente diferentes
SELECT INTO OUTFILE
cria um arquivo de textoINSERT INTO SELECT
carrega uma tabela dos resultados doSELECT
ATUALIZAÇÃO 2014-12-11 12:21 EST
A única coisa em que consigo pensar nesse contexto é o ponto no tempo dos dados e quando você os está usando. Com ambos os tipos de operações, haverá algum bloqueio compartilhado implícito.
Com
SELECT INTO OUTFILE
, você está preparando um resultado e salvando-o externamente. Carregar esses dados em uma tabela usandoLOAD DATA INFILE
não envolverá nenhum bloqueio compartilhado durante o processo de carregamento. Lembre-se de queSELECT INTO OUTFILE
isso incorrerá em E/S de disco e ainda imporá algum armazenamento em cache ao longo do caminho.Com
INSERT INTO SELECT
, os bloqueios compartilhados provavelmente teriam que durar mais no InnoDB porque você está bloqueando linhas e usando essas mesmas linhas para INSERT em outra tabela.Portanto, se eu estivesse procurando por um bônus de desempenho, eu daria a vantagem
INSERT INTO SELECT
porque você está fazendo a mesma quantidade de bloqueio de linhaSELECT INTO OUTFILE
compartilhadaLOAD DATA INFILE
. Claro, você teria que comparar os dois métodos com seu conjunto de dados. O que poderia ser um bônus de desempenho para um conjunto de dados pode ser um custo de desempenho para outro conjunto de dados.ATUALIZAÇÃO 2014-12-17 00:00 EST
Seu comentário
A única resposta autorizada viria da documentação do MySQL.
Primeiro, o que a documentação do MySQL LOAD DATA INFILE diz?
Dois parágrafos depois , diz
Quando você olha para Speed of INSERT Statements , ele diz o seguinte:
As coisas começam a parecer um pouco nebulosas neste ponto porque você deve ajustar o processo de carregamento em termos do mecanismo de armazenamento. MyISAM é bastante direto nesta declaração porque o buffer de inserção em massa é apenas para MyISAM e LOAD DATA INFILE aproveitará o buffer de inserção em massa . InnoDB não .
Dê uma olhada nesta representação pictórica do InnoDB (Percona CTO Vadim Tchachenko)
Existem outras considerações para ajustar as opções , mas
LOAD DATA INFILE
literalmente colocar tudo no InnoDB Buffer Pool, canalizando as alterações por meio do Log Buffer, Double Write Buffer, Insert Buffer (se a tabela de destino tiver índices não exclusivos), Redo Logs (ib_logfile0,ib_logfile1) e o Arquivo Físico da Tabela. É aqui que os benefícios de LOAD DATA INFILE devem ser anulados.eu escrevi sobre isso
Feb 06, 2012
: LOAD DATA (400k rows) INFILE leva cerca de 7 minutos, não pode matar o processo de "logging slow query"?Apr 20, 2012
: Por que 'LOAD DATA INFILE' é mais rápido que as instruções INSERT normais?Jul 13, 2012
: Mysql load from infile travado esperando no disco rígidoJan 11, 2013
: MySQL LOAD DATA INFILE diminui em 80% após alguns shows de entrada com o mecanismo InnoDBEPÍLOGO
Como eu já disse na minha atualização anterior para esta resposta
Basicamente, você terá que testar
SELECT INTO OUTFILE/LOAD DATA INFILE
contraINSERT INTO SELECT
. Pode ser 6 de um, meia dúzia do outro para um conjunto de dados e uma vitória terrestre para outro conjunto de dados.Tudo dito a partir do MySQL Docs e de minhas postagens anteriores, ainda dou vantagem ao
INSERT INTO SELECT
. Você apenas terá que testar os dois métodos.