sql >> Database >  >> RDS >> Mysql

Als u op datum bestelt, vertraagt ​​het gebruik van tijdelijk de zoekopdracht

Ik denk dat de meeste problemen hier en bij soortgelijke vragen voortkomen uit een misverstand over hoe MySQL (en andere databases) indexen gebruikt om te sorteren. Het antwoord is:MySQL gebruikt geen indexen om te sorteren, het kan alleen gegevens in de volgorde van een index of in de tegenovergestelde richting lezen. Als je toevallig wilt dat de gegevens worden gerangschikt in de volgorde van de momenteel gebruikte index - je hebt geluk, anders wordt het resultaat gesorteerd (vandaar filesort in EXPLAIN)

Die volgorde van het hele resultaat hangt meestal af van welke tafel de eerste in de join was. En als je naar je EXPLAIN kijkt, zul je zien dat de join begint vanaf de tabel 'log_codes' (omdat deze veel kleiner is).

Wat je eigenlijk nodig hebt, is een samengestelde index (partner_id, datum) op 'log_entries', een dekkende samengestelde index (log_code, category_overview, log_desc) voor 'log_codes', verander 'INNER JOIN' in 'STRAIGHT_JOIN' om de join-volgorde te forceren, en sorteer op 'datum' DESC (deze index zal gelukkig ook dekken).

UPD1 :Sorry, ik heb de index voor de eerste tabel verkeerd getypt:het zou (partner_id, log_code, date) moeten zijn .

MySQL kan ofwel rechtstreeks gegevens uitvoeren zolang u akkoord gaat met de volgorde waarin het het krijgt, of gegevens in een tijdelijke tabel plaatsen, sorteren en vervolgens uitvoeren. Wanneer u op een veld bestelt uit een niet-eerste tabel in joins, moet MySQL gegevens sorteren (niet alleen uitvoer in de volgorde van een index) en om gegevens te sorteren heeft het een tijdelijke tabel nodig.

Om rijen 50000,25 uit te voeren, moet MySQL hoe dan ook de eerste 50000 ophalen en deze overslaan. Omdat ik een kolom in de index heb gemist, heeft MySQL niet alleen de index gescand, maar voor elk item een ​​extra zoekactie op schijf gemaakt voor log_code waarde. Met de dekkende index zou dat veel sneller moeten zijn, aangezien alle gegevens uit de index gehaald kunnen worden.

UPD2 :probeer de index te forceren:

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. MySQL hoe decimale waarde te converteren naar graad, minuut, seconde

  2. Flask-SQLAlchemy - directe verbindingen met meerdere databases

  3. android.content.res.Resources$NotFoundException:String resource ID #0x2 Database

  4. Kan mysql2 gem niet installeren op macOS Sierra