我需要优化我的查询,这是运行非常慢,但不知道如何做。它包含一个子查询,这使得它非常慢。如果我删除了内联查询,那么它会运行得很好。
查询为:
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 wherea)如何阅读此解释计划并了解其含义?
b)如何优化此查询?
发布于 2016-06-26 03:45:58
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中,我预计“全部”会变成“范围”,而“文件排序”会消失。
发布于 2016-06-15 17:23:37
要理解完整的explain-plan,您应该阅读documentation,但它包含的最重要的信息是mysql使用的索引,或者,更具启发性的是,它没有使用索引。
对于您的DEPENDENT SUBQUERY (即您的“内联查询”),它没有使用好的索引,这会使您的查询速度变慢,因此您需要在表rej_job_status上添加索引rej_job_status(booking_id)。
创建它,测试它并再次检查您的explain计划,然后它将在您的DEPENDENT SUBQUERY的key下列出该新索引。
另一个优化可能是为表rej_booking添加一个索引rej_booking(booking_time)。这取决于您的数据是否改善了查询,但您应该尝试一下,因为目前,mysql没有为该选择使用索引。
https://stackoverflow.com/questions/37827693
复制相似问题