Em primeiro lugar, para lidar com as questões específicas que você levanta:
-
Conforme documentado emCREATE INDEXSintaxe :
Portanto, antes mesmo de considerar oHASHindexação, deve-se estar ciente de que é apenas disponível naMEMORYeNDBmecanismos de armazenamento:então pode nem ser uma opção para você.
Além disso, esteja ciente de que os índices nas combinações deIDeLookupsozinho pode não ser o ideal, pois seuWHEREpredicado também filtra emtablea.Elg_IDpart1etableb.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.