优化前的慢SQL:3.8s

EXPLAIN SELECTproduct.id AS product_id,product.CODE AS product_code,product.NAME AS product_name,product.remarks AS product_remarks,warnLabel.storage_num_code AS "productStorageWarningLabel.storageNumCode",warnLabel.storage_duration_code AS "productStorageWarningLabel.storageDurationCode",warnLabel.product_retail_price_code AS "productStorageWarningLabel.productRetailPriceCode",sum(STORAGE.total_num ) AS "allStorageTotalNum",sum(STORAGE.total_num ) - sum(entityInfo.canNotUseEntityNum) AS "allStorageCanUseNum",sum(STORAGE.total_price ) AS "allStorageTotalPrice"
FROMtkl_product productLEFT JOIN tkl_product_type productType ON productType.id = product.product_type_idLEFT JOIN tkl_product_brand_series dictBrand ON dictBrand.id = product.dict_brand_idLEFT JOIN tkl_product_brand_series dictSeries ON dictSeries.id = product.dict_series_idLEFT JOIN tkl_product_supplier dictSupplier ON dictSupplier.id = product.dict_supplier_idLEFT JOIN tkl_dict_item dictProperty ON dictProperty.id = product.dict_property_idLEFT JOIN tkl_product_storage STORAGE ON STORAGE.product_id = product.id AND STORAGE.del_flag = 0LEFT JOIN (SELECTe.product_id AS product_id,e.dept_id AS dept_id,count(1 ) AS canNotUseEntityNum FROMtkl_product_entity e WHEREe.team_id = 16 AND e.STATUS = '待出库' AND e.del_flag = 0 GROUP BYproduct_id,dept_id ) entityInfo ON entityInfo.product_id = STORAGE.product_id AND entityInfo.dept_id = STORAGE.dept_idLEFT JOIN tkl_product_storage_warning_label warnLabel ON STORAGE.id = warnLabel.product_storage_id
WHEREproduct.del_flag = 0 AND product.team_id = 16 AND STORAGE.dept_id IN (2131)
GROUP BYproduct.id,product_code,product_remarks
HAVINGsum(STORAGE.total_num ) > 0
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY product ref PRIMARY,idx_teamid_delflag,index_team_id idx_teamid_delflag 4 const 2594 10 Using index condition; Using temporary; Using filesort
1 PRIMARY productType eq_ref PRIMARY PRIMARY 4 tingkelai.product.product_type_id 1 100 Using index
1 PRIMARY dictBrand eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_brand_id 1 100 Using index
1 PRIMARY dictSeries eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_series_id 1 100 Using index
1 PRIMARY dictSupplier eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_supplier_id 1 100 Using index
1 PRIMARY dictProperty eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_property_id 1 100 Using index
1 PRIMARY STORAGE ref index_tkl_product_storage_product_id index_tkl_product_storage_product_id 4 tingkelai.product.id 134 5 Using where
1 PRIMARY ref <auto_key0> <auto_key0> 8 tingkelai.product.id,tingkelai.STORAGE.dept_id 2 100
1 PRIMARY warnLabel eq_ref u_product_storage_warning_label u_product_storage_warning_label 8 tingkelai.STORAGE.id 1 100 Using where
2 DERIVED e ref u_tkl_product_entity,index_tkl_product_entity_status_code,index_tkl_product_entity_teamId_deptId,idx_productid_deptid_status_delflag,idx_code_productid_deptid_teamid_status index_tkl_product_entity_status_code 767 const 93 7.84 Using index condition; Using where; Using temporary; Using filesort

优化后的SQL:1.9s

EXPLAIN SELECTproduct.id AS product_id,product.CODE AS product_code,product.NAME AS product_name,product.remarks AS product_remarks,warnLabel.storage_num_code AS "productStorageWarningLabel.storageNumCode",warnLabel.storage_duration_code AS "productStorageWarningLabel.storageDurationCode",warnLabel.product_retail_price_code AS "productStorageWarningLabel.productRetailPriceCode",sum(STORAGE.total_num ) AS "allStorageTotalNum",sum(STORAGE.total_num ) - sum(entityInfo.canNotUseEntityNum) AS "allStorageCanUseNum",sum(STORAGE.total_price ) AS "allStorageTotalPrice"
FROMtkl_product productLEFT JOIN tkl_product_type productType ON productType.id = product.product_type_idLEFT JOIN tkl_product_brand_series dictBrand ON dictBrand.id = product.dict_brand_idLEFT JOIN tkl_product_brand_series dictSeries ON dictSeries.id = product.dict_series_idLEFT JOIN tkl_product_supplier dictSupplier ON dictSupplier.id = product.dict_supplier_idLEFT JOIN tkl_dict_item dictProperty ON dictProperty.id = product.dict_property_idLEFT JOIN tkl_product_storage STORAGE ON STORAGE.product_id = product.id AND STORAGE.del_flag = 0LEFT JOIN (SELECTe.product_id AS product_id,e.dept_id AS dept_id,count(1 ) AS canNotUseEntityNum FROMtkl_product_entity e WHEREe.team_id = 16 AND e.STATUS = '待出库' AND e.del_flag = 0 GROUP BYproduct_id,dept_id ) entityInfo ON entityInfo.product_id = STORAGE.product_id AND entityInfo.dept_id = STORAGE.dept_idLEFT JOIN tkl_product_storage_warning_label warnLabel ON STORAGE.id = warnLabel.product_storage_id
WHEREproduct.del_flag = 0 AND product.team_id = 16 AND STORAGE.dept_id IN (2131)
GROUP BYproduct.id
HAVINGsum(STORAGE.total_num ) > 0
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY product index PRIMARY,idx_teamid_delflag,index_team_id index_team_id 4 4732 5.48 Using where
1 PRIMARY productType eq_ref PRIMARY PRIMARY 4 tingkelai.product.product_type_id 1 100 Using index
1 PRIMARY dictBrand eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_brand_id 1 100 Using index
1 PRIMARY dictSeries eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_series_id 1 100 Using index
1 PRIMARY dictSupplier eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_supplier_id 1 100 Using index
1 PRIMARY dictProperty eq_ref PRIMARY PRIMARY 4 tingkelai.product.dict_property_id 1 100 Using index
1 PRIMARY STORAGE ref index_tkl_product_storage_product_id index_tkl_product_storage_product_id 4 tingkelai.product.id 134 5 Using where
1 PRIMARY ref <auto_key0> <auto_key0> 8 tingkelai.product.id,tingkelai.STORAGE.dept_id 2 100
1 PRIMARY warnLabel eq_ref u_product_storage_warning_label u_product_storage_warning_label 8 tingkelai.STORAGE.id 1 100 Using where
2 DERIVED e ref u_tkl_product_entity,index_tkl_product_entity_status_code,index_tkl_product_entity_teamId_deptId,idx_productid_deptid_status_delflag,idx_code_productid_deptid_teamid_status index_tkl_product_entity_status_code 767 const 93 7.84 Using index condition; Using where; Using temporary; Using filesort

重点区别

优化前

语句

GROUP BY product.id,product_code,product_remarks

EXPLIAN

row extra
2594 Using index condition; Using temporary; Using filesort

优化后

语句

GROUP BY product.id

EXPLIAN

row extra
4732 Using where

之前我写SQL的逻辑是:
SELECT需要用到聚合函数时,非聚合函数的列必须出现在Group By后面!这是个错误的概念!

Group By多个字段逻辑:
例子:group by a,b,c
解释:先按照A字段分组,然后在分组的基础上在按照B字段分一次组,这里避免不了使用临时表和排序,即Using temporary; Using filesort

总结

  1. rows: 这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的。(如上述优化例子中明显优化后的row:4732更多,但是查询速度却明显比之前的row:2594更快!)
  2. extra:执行状态说明,这里如果出现Using temporary,Using filesor就说明sql亟需优化

番外篇

type从最好到最差的连接类型为system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
因此上述sql还可以继续优化,将type:index优化成ref,extra:Using where优化成Using index condition; Using where,1.9s提升到1.8s,有时还是会飙到1.9s,因此效果不是很明显,总而言之,优化主要根据type+row+extra三列的信息综合判断来优化,最终还是以查询效果为主。

参考资料

菜鸟教程-MySql索引优化攻略 (组合索引与前缀索引)
美团-MySQL索引原理及慢查询优化 (最左前缀匹配原则)

SQL优化 - Group By 导致的慢sql相关推荐

  1. MySQL高级 - SQL优化 - group by 优化

    优化group by 语句 由于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作.当然,如果在分组的时候还使用了其他的一些聚 ...

  2. mysql sql优化_浅谈mysql中sql优化

    说到sql优化,一般有几个步骤呢,在网上看到了一篇很不错的帖子.在这分享一下吧,也是自己学习的一个过程. 一.查找慢查询 1.1.查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; ...

  3. 数据库sql优化总结之5--数据库SQL优化大总结

    数据库SQL优化大总结 小编最近几天一直未出新技术点,是因为小编在忙着总结整理数据库的一些优化方案,特此奉上,优化总结较多,建议分段去消化,一口吃不成pang(胖)纸 一.百万级数据库优化方案 1.对 ...

  4. mysql优化和sql优化一样吗_mysql数据库的sql优化原则和常见误区

    gistfile1.txt 优化目标 1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作 所占用的,减少 IO 次数 ...

  5. SQL优化:紧急情况下提高SQL性能竟是这样实现的!(文中有惊喜)

    关注我们获得更多精彩 作者 | 黄堋 ,多年一线 Oracle DBA 经验,长期服务电信.电网.医院.政府等行业客户.擅长数据库优化.数据库迁移升级.数据库故障处理. 在某运营商的优化经历中曾经遇到 ...

  6. mysql sql 优化 博客园_Mysql的SQL优化指北

    概述 在一次和技术大佬的聊天中被问到,平时我是怎么做Mysql的优化的?在这个问题上我只回答出了几点,感觉回答的不够完美,所以我打算整理一次SQL的优化问题. 要知道怎么优化首先要知道一条SQL是怎么 ...

  7. 实战演练:通过伪列、虚拟列实现SQL优化

    关注"数据和云",精彩不容错过 本文是技术同仁 蔡亮 在日常工作中通过试验,总结出的一些技巧方案,供大家参考学习.在此,感谢蔡亮的供稿分享,希望大家也可以后续将学习工作中遇到的问题 ...

  8. 这一篇说明大多数SQL优化的面试问题

    一:创建的索引有没有被使用到 MySQL提供了explain命令来查看语句的执行计划. 二:SQL的生命周期 应用服务器与数据库服务器建立一个连接 数据库进程拿到请求sql 解析并生成执行计划,执行 ...

  9. SQL优化核心思想:或许你不知道的5条优化技巧

    点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书. --异步小编 随着系统的数据量逐年增加,并发量也成倍增长,SQL性能越来越成为IT系统 ...

最新文章

  1. python教程:%s、%d、%f的使用
  2. Android 用户信息管理程序【SQLite数据库、多选框、单选按钮】
  3. boost::hana::make_optional用法的测试程序
  4. MySQL单列索引与复合索引选择
  5. 定义简单类-接收对象的变量同样是对对象的引用
  6. gprs连接中断记录_请收好!脉搏波血压计连接天天血压APP使用指南
  7. 平面设计 前端_我如何在5个月内从平面设计师过渡到前端开发人员
  8. php oauth 扩展,PHP扩展之Web服务(一)——OAuth
  9. panzer 电力项目十一--hibernate操作大文本字段Blob和Clob
  10. oracle建表语句string,编程式Mybatis获取oracle表创建表语句
  11. BZOJ2957楼房重建
  12. quartus仿真22:优先编码器74148的级联(详细)
  13. 普元BPS:唯一零错误的流程平台
  14. HelloWorld入门程序
  15. jQuery事件命名空间多事件绑定自定义事件js 命名空间 javascript命名空间
  16. win7计算机自动关机设置在哪里设置方法,win7怎么设置自动关机【详细步骤】
  17. 计算机组装与维护过程与方法,计算机组装与维护的实训报告
  18. 修心三不:不生气不计较不抱怨
  19. 结巴分词有前空格_jieba英文空格分词问题
  20. ROS2_Foxy学习1——前言与安装

热门文章

  1. 安工大2020计算机调剂,2020考研最新调剂信息,安大、安工大、东北林大211等高校调剂信息...
  2. 先学python还是ros_ROS学习入门(抛砖引玉篇)
  3. java list 子集_一个List的全部子集
  4. win7 php7 redis扩展,win7 php5.6 redis扩展
  5. JNI:本地代码调用Java代码
  6. USACO Farmer_John收苹果 (dp)
  7. 《网站分析实战--如何以数据驱动决策,提升网站价值》学习笔记
  8. 教你如何快速突破TikTok限流--TK领航社tiktok苹果版安卓版下载教程
  9. windows下SourceTree的安装位置,用于创建快捷方式到桌面
  10. 云队友丨真正限制你的,是你对潜力的一无所知