加入收藏 | 设为首页 | 会员中心 | 我要投稿 西安站长网 (https://www.029zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

如何去写一手好SQL

发布时间:2019-10-29 06:19:03 所属栏目:建站 来源:今头日条一小马奔腾
导读:副标题#e# MySQL性能 数据表设计 索引优化 SQL优化 其他数据库 博主负责的项目主要采用阿里云数据库MySQL,最近频繁出现慢SQL告警,执行时间最长的竟然高达5分钟。导出日志后分析,主要原因竟然是没有命中索引和没有分页处理。其实这是非常低级的错误,我不

博主小时候看到鱼塘挖开小口子放水,水面有各种漂浮物。浮萍和树叶总能顺利通过出水口,而树枝会挡住其他物体通过,有时还会卡住,需要人工清理。MySQL就是鱼塘,最大并发数和网络带宽就是出水口,用户SQL就是漂浮物。

不带分页参数的查询或者影响大量数据的update和delete操作,都是树枝,我们要把它打散分批处理,举例说明:

业务描述:更新用户所有已过期的优惠券为不可用状态。

SQL语句:

  1. update status=0 FROM `coupon` WHERE expire_date <= #{currentDate} and status=1; 

如果大量优惠券需要更新为不可用状态,执行这条SQL可能会堵死其他SQL,分批处理伪代码如下:

  1. int pageNo = 1; 
  2. int PAGE_SIZE = 100; 
  3. while(true) { 
  4.  List<Integer> batchIdList = queryList('select id FROM `coupon` WHERE expire_date <= #{currentDate} and status = 1 limit #{(pageNo-1) * PAGE_SIZE},#{PAGE_SIZE}'); 
  5.  if (CollectionUtils.isEmpty(batchIdList)) { 
  6.  return; 
  7.  } 
  8.  update('update status = 0 FROM `coupon` where status = 1 and id in #{batchIdList}') 
  9.  pageNo ++; 

操作符<>优化

通常<>操作符无法使用索引,举例如下,查询金额不为100元的订单:

  1. select id from orders where amount != 100; 

如果金额为100的订单极少,这种数据分布严重不均的情况下,有可能使用索引。鉴于这种不确定性,采用union聚合搜索结果,改写方法如下:

  1. (select id from orders where amount > 100) 
  2.  union all 
  3. (select id from orders where amount < 100 and amount > 0) 

OR优化

在Innodb引擎下or无法使用组合索引,比如:

  1. select id,product_name from orders where mobile_no = '13421800407' or user_id = 100; 

(编辑:西安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读