For det første for at håndtere de specifikke spørgsmål, du rejser:
-
Som dokumenteret under
CREATE INDEX
Syntaks :Derfor, før du overhovedet overvejer
HASH
indeksering, skal man være opmærksom på, at det kun er tilgængelig iMEMORY
ogNDB
lagringsmotorer:så er måske ikke engang en mulighed for dig.Vær desuden opmærksom på, at indekserer på kombinationer af
ID
ogLookup
alene er muligvis ikke optimalt, da dinWHERE
prædikat filtre også påtablea.Elg_IDpart1
ogtableb.IDpart1
– du kan også drage fordel af at indeksere på disse kolonner. -
Forudsat at de ønskede indekstyper understøttes af storage-motoren, kan du blande dem, som det passer dig.
-
Du kan bruge et indekstip at tvinge MySQL til at bruge andre indekser end dem, som optimeringsværktøjet ellers ville have valgt.
-
Det er normalt smart nok, men ikke altid. I dette tilfælde har den dog sandsynligvis fastslået, at kardinaliteten af indeksene er sådan, at det er bedre at bruge dem, som den har valgt.
Nu, afhængigt af den version af MySQL, du bruger, har tabeller afledt af underforespørgsler muligvis ikke nogen indekser på dem, som kan bruges til yderligere behandling:som følge heraf forbindes med b
kan kræve en fuld scanning af den afledte tabel (der er utilstrækkelig information i dit spørgsmål til at bestemme præcist, hvor meget af et problem dette kan være, men schema1.tableb
at have 1,5 millioner optegnelser tyder på, at det kan være en væsentlig faktor).
Se Optimering af underforespørgsler for mere information.
Man bør derfor forsøge at undgå at bruge afledte tabeller, hvis det overhovedet er muligt. I dette tilfælde ser der ikke ud til at være noget formål med din afledte tabel, da man blot kunne tilslutte sig schema1.tablea
og schema1.tableb
direkte:
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 eneste, der er gået tabt, er filteret for DISTINCT
poster, men duplikerede poster vil simpelthen (forsøg på) at overskrive opdaterede værdier med de samme værdier igen - hvilket ikke vil have nogen effekt, men kan have vist sig meget dyrt (især med så mange poster i den tabel).
Brugen af ORDER BY
i den afledte tabel var meningsløs, da den ikke kunne stoles på for at opnå en bestemt rækkefølge til UPDATE
, hvorimod den i denne reviderede version vil sikre, at alle opdateringer, der overskriver tidligere, finder sted i den angivne rækkefølge:men er det nødvendigt? Måske kan den fjernes og spare på enhver sorteringsoperation.
Man bør tjekke prædikaterne i WHERE
klausul:er de alle nødvendige (NOT NULL
kontrollerer a.ID
og b.Lookup
, for eksempel, er overflødige, da enhver sådan NULL
poster vil blive elimineret af JOIN
prædikat)?
Alt i alt efterlader dette os 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
Kun hvis ydeevnen stadig er utilfredsstillende, bør man se nærmere på indekseringen. Er relevante kolonner (dvs. dem, der bruges i JOIN
og WHERE
prædikater) indekseret? Er indeksene valgt til brug af MySQL (husk på, at det kun kan bruge én indeks pr. tabel til opslag:til test af både JOIN
prædikat og filterprædikater:måske har du brug for et passende sammensat indeks)? Tjek forespørgselsudførelsesplanen ved at bruge EXPLAIN
at undersøge sådanne spørgsmål nærmere.