2016-06-15 3 views
0

Мне нужно оптимизировать мой запрос, который работает очень медленно, но не знаю, как это сделать. Он содержит подзапрос, который делает его очень медленным. Если я удалю встроенный запрос, он будет работать очень хорошо.Оптимизация запросов Mysql - очень медленно

Этот запрос:

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 

объяснить план показывает, что это:

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 

а) Как читать это объяснить план и знать, что это значит?

б) Как я могу оптимизировать этот запрос?

ответ

0

Чтобы понять полный текст: explain -plan, вы должны прочитать documentation, но самая важная информация, которую он включает, это индексы, используемые mysql, или, как правило, более показательные, которые он не использует.

Для вашего DEPENDENT SUBQUERY (то есть ваш «встроенный запрос»), он не использует хороший показатель, который делает ваш запрос медленно, так что вам нужно добавить индекс rej_job_status(booking_id) на вашем столе rej_job_status.

Создайте его, проверьте его и проверьте свой план explain еще раз, затем он должен указать этот новый индекс под key для вашего DEPENDENT SUBQUERY.

Другой оптимизацией может быть добавление индекса rej_booking(booking_time) для вашей таблицы rej_booking. Это зависит от ваших данных, если он улучшает запрос, но вы должны попробовать, так как прямо сейчас mysql не использует индекс для этого выбора.

0

booking_time скрывается внутри функции, поэтому INDEX(booking_time) не может быть использован. Это приводит к дорогостоящему сканированию таблицы.

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 

Или это может быть проще (избегая второго расчета даты):

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

В EXPLAIN, я ожидаю, что 'ALL', чтобы стать 'range' и 'Filesort' исчезнуть.

Смежные вопросы