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

Når du bestiller efter datobeskrivelse, sænker brug af midlertidig forespørgslen

Jeg tror, ​​de fleste problemer her og i lignende spørgsmål kommer fra misforståelser af, hvordan MySQL (og andre databaser) bruger indekser til sortering. Svaret er:MySQL bruger ikke indekser til sortering, det kan blot læse data i rækkefølgen af ​​et indeks eller i den modsatte retning. Hvis du tilfældigvis ønskede, at dataene skulle sorteres i rækkefølgen af ​​det aktuelt brugte indeks - er du heldig, ellers vil resultatet blive sorteret (derfor sorterer filer i EXPLAIN)

Det er rækkefølgen af ​​hele resultatet afhænger for det meste af hvilket bord der var det første i sammenføjningen. Og hvis du ser på din EXPLAIN, vil du se, at joinforbindelsen starter fra 'log_codes'-tabellen (fordi den er meget mindre).

Grundlæggende er det, du har brug for, et sammensat indeks (partner_id, dato) på 'log_entries', et dækkende sammensat indeks (log_code, category_overview, log_desc) for 'log_codes', ændre 'INNER JOIN' til 'STRAIGHT_JOIN' for at tvinge sammenføjningen, og bestil efter 'dato' DESC (dette indeks vil heldigvis også dække).

UPD1 :Undskyld, jeg har skrevet forkert i indekset for den første tabel:det skal være (partner_id, log_code, date) .

MySQL kan enten direkte udlæse data, så længe du er enig i den rækkefølge, den får det i, eller lægge data i en midlertidig tabel, anvende sortering og output derefter. Når du bestiller efter et felt fra en ikke-første tabel i joins, skal MySQL sortere data (ikke kun output i rækkefølgen af ​​et indeks), og for at sortere data skal der bruges en midlertidig tabel.

For at outputte rækker 50000,25 skal MySQL alligevel hente de første 50000 og springe dem over. Da jeg gik glip af en kolonne i indekset, skannede MySQL ikke bare indekset, men for hvert element lavede et ekstra opslag på disken for log_code værdi. Med det dækkende indeks burde det være meget hurtigere, da alle data kan hentes fra indekset.

UPD2 :prøv at tvinge indekset:

SELECT log_entries.date, log_codes.log_desc
FROM log_entries FORCE INDEX (IX_partner_code_date)
STRAIGHT_JOIN log_codes
  ON log_codes.log_code = log_entries.log_code
WHERE log_entries.partner_id = 1
  AND log_codes.category_overview = 1
ORDER BY log_entries.date DESC;


  1. PostgreSQL:Den alsidige INSERT

  2. MS SQL Server på Linux vs Windows Performance Test for at se forskellen

  3. mysql SELECT med betingelsespræference

  4. Sådan opretter du en offline internationaliseringsapp:Byg projektstrukturen