En primer lugar, para tratar las cuestiones concretas que planteas:
-
Como se documenta en
CREATE INDEX
Sintaxis :Por lo tanto, incluso antes de considerar
HASH
indexación, se debe tener en cuenta que es solamente disponible en laMEMORY
yNDB
Motores de almacenamiento:puede que ni siquiera sea una opción para usted.Además, tenga en cuenta que los índices en combinaciones de
ID
yLookup
solo puede no ser óptimo, ya que suWHERE
el predicado también filtra entablea.Elg_IDpart1
ytableb.IDpart1
—también puede beneficiarse de la indexación en esas columnas. -
Siempre que los tipos de índice deseados sean compatibles con el motor de almacenamiento, puede mezclarlos como mejor le parezca.
-
Podría usar una sugerencia de índice para obligar a MySQL a usar índices diferentes a los que el optimizador habría seleccionado de otro modo.
-
Es normalmente lo suficientemente inteligente, pero no siempre. En este caso, sin embargo, probablemente ha determinado que la cardinalidad de los índices es tal que es mejor usar los que ha elegido.
Ahora, dependiendo de la versión de MySQL que esté utilizando, es posible que las tablas derivadas de subconsultas no tengan ningún índice que pueda usarse para un procesamiento posterior:en consecuencia, la unión con b
puede requerir un escaneo completo de esa tabla derivada (no hay información suficiente en su pregunta para determinar exactamente qué tan problemático podría ser, pero schema1.tableb
tener 1,5 millones de registros sugiere que podría ser un factor significativo).
Consulte Optimización de subconsultas para más información.
Por lo tanto, se debe tratar de evitar el uso de tablas derivadas en la medida de lo posible. En este caso, no parece haber ningún propósito para su tabla derivada, ya que uno podría simplemente unirse a schema1.tablea
y schema1.tableb
directamente:
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
Lo único que se ha perdido es el filtro para DISTINCT
registros, pero los registros duplicados simplemente (intentarán) sobrescribir los valores actualizados con esos mismos valores nuevamente, lo que no tendrá ningún efecto, pero puede haber resultado muy costoso (especialmente con tantos registros en esa tabla).
El uso de ORDER BY
en la tabla derivada no tenía sentido, ya que no se podía confiar en ella para lograr ningún orden en particular en UPDATE
, mientras que en esta versión revisada se asegurará de que cualquier actualización que sobrescriba las anteriores se realice en el orden especificado, pero ¿es necesario? Tal vez se pueda eliminar y ahorrar en cualquier operación de clasificación.
Uno debe verificar los predicados en WHERE
cláusula:son todos necesarios (el NOT NULL
comprueba en a.ID
y b.Lookup
, por ejemplo, son superfluos dado que cualquier NULL
los registros serán eliminados por JOIN
predicado)?
En total, esto nos deja con:
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
Solo si el rendimiento sigue siendo insatisfactorio, se debe seguir analizando la indexación. Son columnas relevantes (es decir, las utilizadas en JOIN
y WHERE
predicados) indexados? ¿Se están seleccionando los índices para que MySQL los use (tenga en cuenta que solo puede usar uno índice por tabla para búsquedas:para probar tanto el JOIN
predicado y los predicados de filtro:¿quizás necesite un índice compuesto apropiado)? Verifique el plan de ejecución de consultas usando EXPLAIN
para investigar estos problemas más a fondo.