Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Índices de hash do MySQL para otimização


Em primeiro lugar, para lidar com as questões específicas que você levanta:

  1. Conforme documentado em CREATE INDEX Sintaxe :

    Portanto, antes mesmo de considerar o HASH indexação, deve-se estar ciente de que é apenas disponível na MEMORY e NDB 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 de ID e Lookup sozinho pode não ser o ideal, pois seu WHERE predicado também filtra em tablea.Elg_IDpart1 e tableb.IDpart1 — você também pode se beneficiar da indexação nessas colunas.

  2. Desde que os tipos de índice desejados sejam suportados pelo mecanismo de armazenamento, você pode misturá-los como achar melhor.

  3. Você pode usar uma dica de índice para forçar o MySQL a usar índices diferentes daqueles que o otimizador teria selecionado.

  4. É 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.