Mysql
 sql >> Database >  >> RDS >> Mysql

Indici hash MySQL per l'ottimizzazione

In primo luogo, per affrontare le domande specifiche che sollevi:

  1. Come documentato in CREATE INDEX Sintassi :

    Pertanto, prima ancora di considerare HASH indicizzazione, si dovrebbe essere consapevoli che è solo disponibile nella MEMORY e NDB motori di archiviazione:quindi potrebbe non essere nemmeno un'opzione per te.

    Inoltre, tieni presente che gli indici sulle combinazioni di ID e Lookup da solo potrebbe non essere ottimale, come il tuo WHERE il predicato filtra anche su tablea.Elg_IDpart1 e tableb.IDpart1 —potresti trarre vantaggio dall'indicizzazione anche su quelle colonne.

  2. A condizione che i tipi di indice desiderati siano supportati dal motore di archiviazione, puoi combinarli come meglio credi.

  3. Potresti usare un suggerimento indice per forzare MySQL a utilizzare indici diversi da quelli che l'ottimizzatore avrebbe altrimenti selezionato.

  4. È solitamente abbastanza intelligente, ma non sempre. In questo caso, però, ha probabilmente determinato che la cardinalità degli indici è tale per cui è meglio utilizzare quelli che ha scelto.

Ora, a seconda della versione di MySQL che stai utilizzando, le tabelle derivate dalle sottoquery potrebbero non avere alcun indice che possa essere utilizzato per ulteriori elaborazioni:di conseguenza il join con b potrebbe richiedere una scansione completa di quella tabella derivata (non ci sono informazioni sufficienti nella tua domanda per determinare esattamente quanto potrebbe essere un problema, ma schema1.tableb avere 1,5 milioni di record suggerisce che potrebbe essere un fattore significativo).

Vedi Ottimizzazione delle sottoquery per ulteriori informazioni.

Si dovrebbe quindi cercare di evitare di utilizzare tabelle derivate, se possibile. In questo caso, non sembra esserci alcuno scopo per la tua tabella derivata in quanto si potrebbe semplicemente unire schema1.tablea e schema1.tableb direttamente:

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

L'unica cosa che è andata persa è il filtro per DISTINCT record, ma i record duplicati semplicemente (tentano di) sovrascrivere nuovamente i valori aggiornati con quegli stessi valori, il che non avrà alcun effetto, ma potrebbe essersi rivelato molto costoso (specialmente con così tanti record in quella tabella).

L'uso di ORDER BY nella tabella derivata era inutile in quanto non si poteva fare affidamento per ottenere un ordine particolare per l'UPDATE , mentre in questa versione rivista assicurerà che tutti gli aggiornamenti che sovrascrivono quelli precedenti avvengano nell'ordine specificato:ma è necessario? Forse può essere rimosso e salvato su qualsiasi operazione di smistamento.

Si dovrebbero controllare i predicati in WHERE clausola:sono tutti necessari (il NOT NULL controlla a.ID e b.Lookup , ad esempio, sono superflui dato che tali NULL i record verranno eliminati dal JOIN predicato)?

Nel complesso, questo ci lascia 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 se la performance è ancora insoddisfacente si dovrebbe guardare oltre all'indicizzazione. Sono colonne pertinenti (ovvero quelle utilizzate nel JOIN e WHERE predicati) indicizzati? Gli indici sono selezionati per l'uso da parte di MySQL (tieni presente che può usarne solo uno index per table per le ricerche:per testare sia il JOIN predicato e i predicati del filtro:forse hai bisogno di un indice composito appropriato)? Controlla il piano di esecuzione della query utilizzando EXPLAIN per indagare ulteriormente su tali problemi.