2016-06-15 15 views
0

Ich muss meine Abfrage, die sehr langsam läuft, aber nicht wissen, wie es geht zu optimieren. Es enthält eine Unterabfrage, die es sehr langsam macht. Wenn ich die Inline-Abfrage entferne, läuft sie sehr gut.MySQL Abfrage-Optimierung - Sehr langsam

Die Abfrage ist:

EXPLAIN 
SELECT t.service_date, 
     t.service_time, 
     (SELECT js.modified_date FROM rej_job_status js WHERE js.booking_id=b.booking_id ORDER BY id DESC LIMIT 1) `cancel_datetime`, 
     b.booking_id, 
     b.ref_booking_id, 
     b.phone, b.city, 
     b.booking_time, 
     CONCAT(rc.firstname," ",rc.lastname) customer_name, 
     rc.phone_no, 
     rs.service_id, 
     rs.service_name, 
     rct.city_name 
FROM rej_job_details t 
JOIN rej_booking b ON t.booking_id = b.booking_id 
JOIN rej_customer rc ON rc.customer_id = b.customer 
JOIN rej_service rs ON t.service_id = rs.service_id 
JOIN rej_city rct ON rct.city_id=b.city 
WHERE t.act_status = 0 AND DATE(b.booking_time) >= '2016-06-01' 
     AND DATE(b.booking_time) <= '2016-06-14' 
ORDER BY b.booking_time DESC 
LIMIT 0 , 50 

Der Plan erläutern zeigt dies:

id select_type   table type possible_keys  key   key_len ref       rows Extra 
1 PRIMARY    b  ALL  PRIMARY    NULL  NULL NULL      32357 Using where; Using filesort 
1 PRIMARY    rct  eq_ref PRIMARY    PRIMARY  4  crmdb.b.city  1  NULL 
1 PRIMARY    t  ref  booking_id   booking_id 4  crmdb.b.booking_id 1  Using where 
1 PRIMARY    rs  eq_ref PRIMARY,service_id PRIMARY  4  crmdb.t.service_id 1  NULL 
1 PRIMARY    rc  eq_ref PRIMARY    PRIMARY  4  crmdb.b.customer 1  Using where 
2 DEPENDENT SUBQUERY js  index NULL    PRIMARY  4  NULL      1  Using where 

a) Wie dieser Plan erklären lesen und wissen, was es bedeutet?

b) Wie kann ich diese Abfrage optimieren?

Antwort

0

Um den vollen explain -Plan zu verstehen, sollten Sie die documentation lesen, aber die wichtigsten Informationen, die es enthält, sind die Indizes, die mysql verwendet, oder, normalerweise aufschlußreicher, die es nicht benutzt.

Für Ihre DEPENDENT SUBQUERY (das ist Ihre „Inline-Abfrage“), ist es nicht einen guten Index nicht verwendet, die Ihre Abfrage langsam macht, so dass Sie den Index rej_job_status(booking_id) auf Ihrem Tisch rej_job_status hinzufügen müssen.

Erstellen Sie es, testen Sie es und überprüfen Sie Ihren explain Plan erneut, sollte es dann diesen neuen Index unter key für Ihre DEPENDENT SUBQUERY auflisten.

Eine weitere Optimierung könnte darin bestehen, einen Index rej_booking(booking_time) für Ihre Tabelle rej_booking hinzuzufügen. Es hängt von Ihren Daten ab, ob es die Abfrage verbessert, aber Sie sollten es versuchen, da mysql momentan keinen Index für diese Auswahl verwendet.

0

booking_time ist in einer Funktion versteckt, so INDEX(booking_time) kann nicht verwendet werden. Dies führt zu einem kostenintensiven Tabellenscan.

AND DATE(b.booking_time) >= '2016-06-01' 
AND DATE(b.booking_time) <= '2016-06-14' 

->

AND b.booking_time >= '2016-06-01' 
AND b.booking_time < '2016-06-15' -- note 3 differences in this line 

Oder könnte dies einfacher sein (durch die zweite Datumsberechnung zu vermeiden):

AND b.booking_time >= '2016-06-01' 
AND b.booking_time < '2016-06-01' + INTREVAL 2 WEEK 

Im EXPLAIN erwarte ich, dass die 'ALL' werden 'Bereich' und 'Filesort' verschwinden.