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

MySQL Hash-indekser til optimering

For det første for at håndtere de specifikke spørgsmål, du rejser:

  1. 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 i MEMORY og NDB lagringsmotorer:så er måske ikke engang en mulighed for dig.

    Vær desuden opmærksom på, at indekserer på kombinationer af ID og Lookup alene er muligvis ikke optimalt, da din WHERE prædikat filtre også på tablea.Elg_IDpart1 og tableb.IDpart1 – du kan også drage fordel af at indeksere på disse kolonner.

  2. Forudsat at de ønskede indekstyper understøttes af storage-motoren, kan du blande dem, som det passer dig.

  3. Du kan bruge et indekstip at tvinge MySQL til at bruge andre indekser end dem, som optimeringsværktøjet ellers ville have valgt.

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




  1. SQLAlchemy Reflection:Hvordan forespørger jeg data fra specifikke kolonner?

  2. Hvorfor er der huller i min IDENTITY-kolonneværdier?

  3. Forespørgsel med flere likes

  4. Kører MySQL *.sql-filer i PHP