首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mysql查询优化-非常慢

Mysql查询优化-非常慢
EN

Stack Overflow用户
提问于 2016-06-15 14:31:34
回答 2查看 48关注 0票数 1

我需要优化我的查询,这是运行非常慢,但不知道如何做。它包含一个子查询,这使得它非常慢。如果我删除了内联查询,那么它会运行得很好。

查询为:

代码语言:javascript
运行
复制
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 

解释计划显示了以下内容:

代码语言:javascript
运行
复制
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)如何阅读此解释计划并了解其含义?

b)如何优化此查询?

EN

回答 2

Stack Overflow用户

发布于 2016-06-26 03:45:58

booking_time隐藏在函数中,因此不能使用INDEX(booking_time)。这导致了代价高昂的表扫描。

代码语言:javascript
运行
复制
AND DATE(b.booking_time) >= '2016-06-01' 
AND DATE(b.booking_time) <= '2016-06-14' 

-->

代码语言:javascript
运行
复制
AND b.booking_time >= '2016-06-01' 
AND b.booking_time <  '2016-06-15' -- note 3 differences in this line

或者,这可能会更简单(通过避免第二次日期计算):

代码语言:javascript
运行
复制
AND b.booking_time >= '2016-06-01' 
AND b.booking_time <  '2016-06-01' + INTREVAL 2 WEEK

EXPLAIN中,我预计“全部”会变成“范围”,而“文件排序”会消失。

票数 1
EN

Stack Overflow用户

发布于 2016-06-15 17:23:37

要理解完整的explain-plan,您应该阅读documentation,但它包含的最重要的信息是mysql使用的索引,或者,更具启发性的是,它没有使用索引。

对于您的DEPENDENT SUBQUERY (即您的“内联查询”),它没有使用好的索引,这会使您的查询速度变慢,因此您需要在表rej_job_status上添加索引rej_job_status(booking_id)

创建它,测试它并再次检查您的explain计划,然后它将在您的DEPENDENT SUBQUERYkey下列出该新索引。

另一个优化可能是为表rej_booking添加一个索引rej_booking(booking_time)。这取决于您的数据是否改善了查询,但您应该尝试一下,因为目前,mysql没有为该选择使用索引。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37827693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档