sql >> Databasteknik >  >> RDS >> Mysql

När du beställer efter beskrivning av datum, bromsar användningen av temporär sökfrågan

Jag tror att de flesta problem här och i liknande frågor kommer från missförstånd av hur MySQL (och andra databaser) använder index för sortering. Svaret är:MySQL använder inte index för sortering, det kan bara läsa data i indexordningen eller i motsatt riktning. Om du råkade vilja att uppgifterna skulle sorteras i den ordning som för närvarande används index - du har tur, annars kommer resultatet att sorteras (därav filsortera i EXPLAIN)

Det är ordningen på hela resultatet beror mest på vilket bord som var först i sammanfogningen. Och om du tittar på din EXPLAIN kommer du att se att kopplingen börjar från 'log_codes'-tabellen (eftersom den är mycket mindre).

I grund och botten, vad du behöver är ett sammansatt index (partner_id, datum) på 'log_entries', ett täckande sammansatt index (log_code, category_overview, log_desc) för 'log_codes', ändra 'INNER JOIN' till 'STRAIGHT_JOIN' för att tvinga fram sammanfogningsordern, och ordna efter 'datum' DESC (det här indexet kommer lyckligtvis att täcka också).

UPD1 :Jag är ledsen, jag skrev fel i indexet för den första tabellen:det ska vara (partner_id, log_code, date) .

MySQL kan antingen mata ut data direkt så länge du håller med om den ordning som den får den i, eller lägga data i en tillfällig tabell, tillämpa sortering och utdata då. När du beställer efter ett fält från en icke-första tabell i joins måste MySQL sortera data (inte bara matas ut i indexordningen) och för att sortera data behöver den en temporär tabell.

För att mata ut rader 50000,25 måste MySQL ändå hämta de första 50000 och hoppa över dem. Eftersom jag missade en kolumn i indexet, skannade MySQL inte bara indexet utan gjorde en extra på skivuppslagning för varje objekt för log_code värde. Med det täckande indexet borde det vara mycket snabbare, eftersom all data kan hämtas från indexet.

UPD2 :försök tvinga fram indexet:

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. Hur installerar man Python MySQLdb-modulen med pip?

  2. IS NOT NULL-testet för en post returnerar inte TRUE när variabeln är inställd

  3. Vad är lagringsstorleken för BIT(1)?

  4. Skyddar mysql_real_escape_string() HELT mot SQL-injektion?