Em primeiro lugar, para lidar com as questões específicas que você levanta:
-
Conforme documentado emCREATE INDEX
Sintaxe :
Portanto, antes mesmo de considerar oHASH
indexação, deve-se estar ciente de que é apenas disponível naMEMORY
eNDB
mecanismos de armazenamento:então pode nem ser uma opção para você.
Além disso, esteja ciente de que os índices nas combinações deID
eLookup
sozinho pode não ser o ideal, pois seuWHERE
predicado também filtra emtablea.Elg_IDpart1
etableb.IDpart1
— você também pode se beneficiar da indexação nessas colunas.
-
Desde que os tipos de índice desejados sejam suportados pelo mecanismo de armazenamento, você pode misturá-los como achar melhor.
-
Você pode usar uma dica de índice para forçar o MySQL a usar índices diferentes daqueles que o otimizador teria selecionado.
-
É geralmente inteligente o suficiente, mas nem sempre. Neste caso, no entanto, provavelmente determinou que a cardinalidade dos índices é tal que é melhor usar aqueles que escolheu.
Agora, dependendo da versão do MySQL que você está usando, as tabelas derivadas de subconsultas podem não ter nenhum índice que possa ser usado para processamento adicional:consequentemente, a junção com
b
pode exigir uma verificação completa dessa tabela derivada (não há informações suficientes em sua pergunta para determinar exatamente o quanto isso pode ser um problema, mas schema1.tableb
ter 1,5 milhão de registros sugere que poderia ser um fator significativo). Consulte Otimização de subconsulta Para maiores informações.
Deve-se, portanto, tentar evitar o uso de tabelas derivadas, se possível. Nesse caso, não parece haver nenhum propósito para sua tabela derivada, pois pode-se simplesmente unir
schema1.tablea
e schema1.tableb
diretamente:UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND a.ID IS NOT NULL
AND b.IDpart1 IS NOT NULL
AND b.Lookup IS NOT NULL
ORDER BY ID, Lookup
A única coisa que foi perdida é o filtro para
DISTINCT
registros, mas registros duplicados simplesmente (tentarão) substituir valores atualizados por esses mesmos valores novamente - o que não terá efeito, mas pode ter se mostrado muito caro (especialmente com tantos registros nessa tabela). O uso de
ORDER BY
na tabela derivada era inútil, pois não podia ser confiável para obter qualquer ordem específica para o UPDATE
, enquanto nesta versão revisada garantirá que quaisquer atualizações que substituam as anteriores ocorram na ordem especificada:mas isso é necessário? Talvez possa ser removido e economizar em qualquer operação de classificação. Deve-se verificar os predicados no
WHERE
cláusula:todos eles são necessários (o NOT NULL
verifica em a.ID
e b.Lookup
, por exemplo, são supérfluos, dado que qualquer NULL
registros serão eliminados pelo JOIN
predicado)? Ao todo, isso nos deixa com:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND b.IDpart1 IS NOT NULL
Somente se o desempenho ainda for insatisfatório deve-se olhar mais para a indexação. São colunas relevantes (ou seja, aquelas usadas no
JOIN
e WHERE
predicados) indexados? Os índices estão sendo selecionados para uso pelo MySQL (lembre-se de que ele só pode usar um índice por tabela para pesquisas:para testar o JOIN
predicado e os predicados de filtro:talvez você precise de um índice composto apropriado)? Verifique o plano de execução da consulta usando EXPLAIN
investigar melhor tais questões.