För det första, för att ta itu med de specifika frågor som du tar upp:
-
Som dokumenterats under
CREATE INDEX
Syntax :Därför, innan du ens överväger
HASH
indexering bör man vara medveten om att det är endast tillgängligt iMEMORY
ochNDB
lagringsmotorer:så kanske inte ens är ett alternativ för dig.Tänk dessutom på att indexerar på kombinationer av
ID
ochLookup
ensam kanske inte är optimal, eftersom dinWHERE
Predikat filtrerar även påtablea.Elg_IDpart1
ochtableb.IDpart1
– du kan ha nytta av att indexera på dessa kolumner också. -
Förutsatt att de önskade indextyperna stöds av lagringsmotorn kan du blanda dem som du vill.
-
Du kan använda ett indextips för att tvinga MySQL att använda andra index än de som optimeraren annars skulle ha valt.
-
Det är vanligtvis smart nog, men inte alltid. I det här fallet har den dock troligen bestämt att indexens kardinalitet är sådan att det är bättre att använda de som den har valt.
Nu, beroende på vilken version av MySQL du använder, kanske tabeller härledda från underfrågor inte har några index på sig som kan användas för vidare bearbetning:följaktligen sammanfogningen med b
kan kräva en fullständig genomsökning av den härledda tabellen (det finns inte tillräckligt med information i din fråga för att avgöra exakt hur mycket av ett problem detta kan vara, men schema1.tableb
att ha 1,5 miljoner poster tyder på att det kan vara en betydande faktor).
Se Optimering av undersökning för mer information.
Man bör därför försöka undvika att använda härledda tabeller om det alls är möjligt. I det här fallet verkar det inte finnas något syfte med din härledda tabell eftersom man helt enkelt skulle kunna gå med i schema1.tablea
och schema1.tableb
direkt:
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
Det enda som har gått förlorat är filtret för DISTINCT
poster, men dubbletter av poster kommer helt enkelt att (försöka) skriva över uppdaterade värden med samma värden igen – vilket inte kommer att ha någon effekt, men kan ha visat sig vara mycket kostsamt (särskilt med så många poster i den tabellen).
Användningen av ORDER BY
i den härledda tabellen var meningslöst eftersom det inte gick att lita på för att uppnå någon speciell ordning till UPDATE
, medan den i denna reviderade version kommer att säkerställa att alla uppdateringar som skriver över tidigare sker i den angivna ordningen:men är det nödvändigt? Kanske kan den tas bort och spara på valfri sorteringsoperation.
Man bör kontrollera predikaten i WHERE
klausul:är de alla nödvändiga (NOT NULL
kontrollerar a.ID
och b.Lookup
, till exempel, är överflödiga med tanke på att någon sådan NULL
poster kommer att elimineras av JOIN
predikat)?
Sammantaget lämnar detta oss med:
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
Endast om prestandan fortfarande är otillfredsställande bör man titta vidare på indexeringen. Är relevanta kolumner (dvs. de som används i JOIN
och WHERE
predikat) indexerade? Väljs indexen för användning av MySQL (tänk på att den bara kan använda ett index per tabell för uppslagningar:för att testa både JOIN
predikat och filterpredikat:kanske du behöver ett lämpligt sammansatt index)? Kontrollera exekveringsplanen för fråge genom att använda EXPLAIN
att undersöka sådana frågor ytterligare.