mysql5.7 执行计划_MySQL 5.7 优化不能只看执行计划

就这么一条SQL要40s,看执行计划,发现rows很小,神奇了。

SELECT T1.* FROM

(SELECT

T.*,

R.LOCATION_DEPART_ID AS locationDepartId,

CASE

WHEN T.INVENTORY_TYPE = 1

THEN f_fm_getFullLocationName(R.LOCATION_DEPART_ID, '50000050')

WHEN T.INVENTORY_TYPE = 2

THEN

(SELECT f_gg_org_getorgnamepath(OT.ORG_ID,'50000050',ot.org_name)

FROM gg_ORGANIZATION OT

WHERE OT.ORG_ID = R.LOCATION_DEPART_ID)

ELSE ''

END AS locationOrOrgName,

CASE

WHEN T.INVENTORY_TYPE = 1

THEN f_fm_getFullClassifyName (R.CLASSIFY_ID)

ELSE ''

END AS classifyName,

(SELECT

COUNT(

CASE

WHEN ii.INVENTORY_RESULT = 1 THEN 1

END

)

FROM

FM_INVENTORY I,

FM_INVENTORY_ITEM II

WHERE I.ID = II.INVENTORY_ID

AND I.TASK_ID = T.ID) AS waitInventoryNum

FROM

FM_INVENTORY_TASK T,

FM_INVENTORY_TASK_RANGE R

WHERE T.ID = R.TASK_ID) T1

WHERE 1 = 1

AND T1.FLOW_STATE = 2;

id  select_type         table       type   key                   key_len  ref                   rows  Extra

--  ------------------  ----------  ------ --------------------  -------  ------------------- ------ -----------

1  PRIMARY              ref               2        const                   8   (NULL)

2  DERIVED             T           ALL    (NULL)                (NULL)   (NULL)                  80  (NULL)

2  DERIVED             R           ref    IDX_RANGE_TASK_ID     111      T.ID                    1   (NULL)

4  DEPENDENT SUBQUERY  I           ref    IDX_INV_TASK_ID       110      T.ID                    1   Using index

4  DEPENDENT SUBQUERY  II          ref    IDX_INV_INVENTORY_ID  110      I.ID                    6   (NULL)

3  DEPENDENT SUBQUERY  OT          eq_ref PRIMARY               98       R.LOCATION_DEPART_ID    1   Using where

第一个感觉是数据库缓存的问题,检查了一下,很多配置都是默认的,于是加了一下。

[mysqld]下面添加

innodb_read_io_threads = 16

innodb_write_io_threads = 16

max_heap_table_size = 159M

tmp_table_size = 159M

sort_buffer_size = 8M

join_buffer_size = 8M

read_buffer_size = 4M

read_rnd_buffer_size = 16M

bulk_insert_buffer_size = 64M

innodb_buffer_pool_instances = 8

innodb_file_per_table = 1

innodb_thread_concurrency = 0

innodb_log_buffer_size = 6M

innodb_log_file_size = 256M

重启数据库之后,发现性能有所提升,还是30s。只能用最传统的办法,把子查询一个个去掉,执行,发现第三个子查询去掉之后秒出。

(SELECT

COUNT(

CASE

WHEN ii.INVENTORY_RESULT = 1 THEN 1

END

)

FROM

FM_INVENTORY I,

FM_INVENTORY_ITEM II

WHERE I.ID = II.INVENTORY_ID

AND I.TASK_ID = T.ID) AS waitInventoryNum

用show profiles诊断发现时间耗在send data上面。

检查了一下FM_INVENTORY_ITEM是明细的数据,接近800万的数据,且大部分数据集中在一个单上。找了下业务,发现是异常问题,把垃圾数据迁移出去,然后执行SQL,秒出。

总结:MySQL里面的执行计划比较弱,有时候不能完全依赖,还是得查每张表实际的大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值