sql >> Base de Datos >  >> RDS >> Mysql

Índices hash de MySQL para optimización

En primer lugar, para tratar las cuestiones concretas que planteas:

  1. 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 la MEMORY y NDB 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 y Lookup solo puede no ser óptimo, ya que su WHERE el predicado también filtra en tablea.Elg_IDpart1 y tableb.IDpart1 —también puede beneficiarse de la indexación en esas columnas.

  2. Siempre que los tipos de índice deseados sean compatibles con el motor de almacenamiento, puede mezclarlos como mejor le parezca.

  3. 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.

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