记一次MySql优化问题

一、背景

此次查询涉及三个大表的联合查询,即: x_location_t, x_account_t, x_application_t ,每张表的记录大概200万条记录,现在需求是联合查询三个表的记录筛选出用户所需要的条件,原始的sql查询语句如下:

select 
al.id, ln.application_id, al.user_account, case al.user_type when 'w3' then "内部用户" when 'others' then '外部用户' end as user_type, al.country_code, al.country_name, al.ip_address, al.province, al.city, al.detail_address, al.earliest_time, al.latest_time, al.create_by, al.create_time, al.update_by, al.update_time, al.source, case al.source when '1' then "userProfile" when '2' then 'IPNET' end as source_desc, a.code appCode, a.name appName 
from x_location_t al 
JOIN x_account_t  ln on ln.user_type = al.user_type and ln.user_account = al.user_account 
JOIN x_application_t   a on ln.application_id = a.id 
WHERE ln.application_id ="39" and al.user_type = "others"
order by al.earliest_time desc limit 10;

前端执行查询时间大概30秒左右,执行sql语句大概15秒左右,测试环境执行报网关超时异常。对上述sql语句进行sql分析发现全部命中索引

EXPLAIN select 
al.id, ln.application_id, al.user_account, case al.user_type when 'w3' then "内部用户" when 'others' then '外部用户' end as user_type, al.country_code, al.country_name, al.ip_address, al.province, al.city, al.detail_address, al.earliest_time, al.latest_time, al.create_by, al.create_time, al.update_by, al.update_time, al.source, case al.source when '1' then "userProfile" when '2' then 'IPNET' end as source_desc, a.code appCode, a.name appName 
from x_location_t al 
JOIN x_account_t ln on ln.user_type = al.user_type and ln.user_account = al.user_account 
JOIN x_application_t a on ln.application_id = a.id 
WHERE ln.application_id ="39" and al.user_type = "others"
order by al.earliest_time desc limit 10;

进行分析发现大部分时间在al.earliest_time desc 倒排序且没有走多表联合查询索引

二、优化

根据业务需求和表的设计进行相关sql语句进行优化操作,分析每层执行sql所需要的时间,发现三个表的查询语句可以整合为单表查询,且查询所花时间不超过1s,优化后的sql语句如下:

select 
al.id, al.user_account, al.user_type , al.country_code, al.country_name, 
al.ip_address, al.province, al.city, al.detail_address, 
al.earliest_time, al.latest_time, al.create_by, al.create_time, al.update_by, al.update_time, al.source
from x_location_t al 
WHERE 
	al.user_type = "others" 
	and exists (select acc.id from x_account_t acc where  acc.user_account = al.user_account and acc.application_id = 39 )
order by al.id desc 
limit 100;

查询命中主键索引:

EXPLAIN select 
al.id, al.user_account, al.user_type , al.country_code, al.country_name, 
al.ip_address, al.province, al.city, al.detail_address, 
al.earliest_time, al.latest_time, al.create_by, al.create_time, al.update_by, al.update_time, al.source
from x_location_t al 
WHERE 
	al.user_type = "others" 
	and exists (select acc.id from x_account_t acc where  acc.user_account = al.user_account and acc.application_id = 39 )
order by al.id desc 
limit 100;

对于x_application_t 表中特定的应用进行查询可以直接取出应用id(上述.application_id = 39 ),加入现有的sql语句中作为条件进行查询,总结在做sql优化过程中建立索引、视图、存储过程都是在原有的sql语句上做优化,有时并不能很好地提高sql执行效率,有时可以结合业务需求和重写sql语句来进行优化,进而从根本上对sql查询的优化。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值