公司订单系统每日订单量庞大,有很多表数据超千万。公司SQL优化这块做的很不好,可以说是没有做,所以导致查询很慢。

正题

  节选某个功能中的一句SQL EXPLAIN 查看执行计划

EXPLAIN + SQL 查看SQL执行计划

    一个索引没用到,受影响行接近2000万,难怪会慢。

    原来的SQL打印出来估计有好几张A4纸,我发个整理后的简版。

    

SELECTCOUNT(t.w_order_id) lineCount,SUM(ROUND(t.feel_total_money / 100, 2)) AS lineTotalFee,SUM(ROUND(t.feel_fact_money / 100, 2)) AS lineFactFee
FROMw_orders_his t
WHERE 1=1
AND DATE_FORMAT(t.create_time, '%Y-%m-%d') >= STR_TO_DATE(#{beginTime},'%Y-%m-%d')
AND DATE_FORMAT(t.create_time, '%Y-%m-%d') <= STR_TO_DATE(#{endTime},'%Y-%m-%d')
AND t.pay_state = #{payState}
AND t.store_id LIKE '%#{storeId}%'
limit 0,10

    这条sql需求是在两千万的表中捞出指定时间和条件的订单进行总数总金额汇总处理。

    优化sql需要根据公司的业务,技术的架构等,且针对不同业务每条SQL的优化都是有差异的。

优化点1:

AND DATE_FORMAT(t.create_time, '%Y-%m-%d') >= STR_TO_DATE(#{beginTime},'%Y-%m-%d') AND DATE_FORMAT(t.create_time, '%Y-%m-%d') <= STR_TO_DATE(#{endTime},'%Y-%m-%d')

  我们知道sql中绝对要减少函数的使用,像左边DATE_FORMAT(t.create_time, '%Y-%m-%d') 是绝对禁止使用的,如果数据库有一百万数据那么就会执行一百万次函数,非常非常影响效率。右边STR_TO_DATE(#{beginTime},'%Y-%m-%d')的函数会执行一次,但还是不建议使用函数。

  所以去掉函数直接使用  >=,<=BETWEEN AND速度就会快很多,但有的数据库设计时间字段只有日期没有时间,所以需要在日期后面拼接时间如:

  "2017-01-01" + " 00:00:00"

   更好的办法是用时间戳,数据库中存时间戳,然后拿时间戳去比较,如:BETWEEN '开始时间时间戳' AND '结束时间时间戳'

优化点2:

AND t.store_id LIKE '%#{storeId}%'

  这句使用了LIKE并且前后匹配,前后匹配会导致索引失效,一般情况下避免使用,应该改成 AND t.store_id LIKE '#{storeId}%'

优化点3:

  一般利用好索引,根据主键、唯一索引查询某一条记录,就算上亿数据查询也是非常快的。但这条sql需要查询数据统计需要用到COUNTSUM,所以可以建立联合索引。

  联合索引有一点需要注意:key index (a,b,c)可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 ,当最左侧字段是常量引用时,索引就十分有效。

  所以把必要字段排放在左边key index(create_time,w_order_id,feel_total_money,feel_fact_money,payState,storeId)

 结果

    优化之前大概几分钟,现在是毫秒级。其实改的东西也不多,避免在语句上踩雷,善用EXPLAIN查询SQL效率。 

    有时间我会举点别的SQL优化的例子

      

     说几点平常可以优化的地方

  • JOIN 后的的条件必须是索引,最好是唯一索引,否则数据一旦很多会直接卡死
  • 一般禁止使用UNIION ON,除非UNION ON 前后的记录数很少 
  • 禁止使用OR
  • 查总数使用COUNT(*)就可以,不需要COUNT(ID),MYSQL会自动优化
  • 数据库字段设置 NOT NULL,字段类型 INT > VARCHAR 越小越好
  • 禁止SELECT  * ,需要确定到使用的字段
  • 一般情况不在SQL中进行数值计算
  • SQL要写的简洁明了

      

  参考

 EXPLAIN type(从上到下,性能从差到好)

  • all 全表查询
  • index 索引全扫描
  • range 索引范围扫描
  • ref 使用非唯一或唯一索引的前缀扫描,返回相同值的记录
  • eq_ref 使用唯一索引,只返回一条记录
  • const,system 单表中最多只有一行匹配,根据唯一索引或主键进行查询
  • null 不访问表或索引就可以直接得到结果

MYSQL 五大引擎

  • ISAM :读取快,不占用内存和存储资源。 不支持事物,不能容错。
  • MyISAM :读取块,扩展多。
  • HEAP :驻留在内存里的临时表格,比ISAM和MyISAM都快。数据是不稳定的,关机没保存,数据都会丢失。
  • InnoDB :支持事物和外键,速度不如前面的引擎块。
  • Berkley(BDB) :支持事物和外键,速度不如前面的引擎块。

  一般需要事物的设为InnoDB,其他设为MyISAM

如何给mysql的海量数据查询优化相关推荐

  1. mysql中groupby会用到索引吗_开发人员不得不知的MySQL索引和查询优化

    本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有 MySQL 基础的开发人员. 索引相关 索引基数 基数是数据列所包含的不同值的数量,例如, ...

  2. MySQL高级之查询优化(索引失效)

    MySQL高级之查询优化(索引失效) 文章目录 MySQL高级之查询优化(索引失效) 一.单表使用索引及常见的索引失效 1.索引失效的案例 2.建议 二.关联查询优化 1.建表 2.案例 3.优化 三 ...

  3. FastDfs与ElasticSearch和Mysql完成海量数据存储搜索功能

    FastDfs与ElasticSearch和Mysql完成海量数据存储搜索功能 先附上项目地址:项目地址 fdfs-es-demo 介绍 springboot+mysql+fastdfs+elasti ...

  4. MySQL索引与查询优化

    目录 About MySQL Why MySQL MySQL Index Why Index 索引是如何工作的 如何使用 创建索引 查看索引 删除索引 索引的使用原则 写操作比较频繁的列慎重加索引 索 ...

  5. 记录一次mysql单表查询优化

    mysql单表查询语句如何优化可以加快速度? 优化 MySQL 单表查询语句的方法有很多,以下是一些常用的优化技巧: 索引优化:创建索引可以加快查询速度.索引可以基于一个或多个列创建,可以大大提高查询 ...

  6. mysql自带查询优化_MySQL之select in 子查询优化的实现

    下面的演示基于MySQL5.7.27版本 一.关于MySQL子查询的优化策略介绍: 子查询优化策略 对于不同类型的子查询,优化器会选择不同的策略. 1. 对于 IN.=ANY 子查询,优化器有如下策略 ...

  7. 高性能MySQL读书笔记---查询优化

    查询优化 查询缓慢的原因 是否向数据库请求了不必要的数据 1.查询时是否返回了全部或者大部分数据然后再进行处理的. 2.进行单查或者多表联查时是否返回了全部列数据.例如: SELECT * FORM ...

  8. MySQL 处理海量数据时的一些优化查询速度方法

    在参与实际项目中,当 MySQL 表的数据量达到百万级时,普通的 SQL 查询效率呈直线下降,而且如果 where 中的查询条件较多时,其查询速度无法容忍.想想可知,假如我们查询淘宝的一个订单详情,如 ...

  9. mysql 回表查询优化_MySQL优化:如何避免回表查询?什么是索引覆盖?

    转自:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962609&idx=1&sn=46e59691257 ...

最新文章

  1. ubuntu/linuxmint如何添加和删除PPA源
  2. DNS and BIND
  3. centos7编译PGSQL9.6并配置UUID
  4. mysql宠物种类表,mysql中的表操作
  5. 生成docker镜像
  6. html绑定按键图片移动,如何使用JS实现用键盘控制图片移动呢?
  7. 解决$router.go(-1)返回上一层页面不刷新页面问题
  8. 信息学奥赛一本通 1057:简单计算器 | OpenJudge NOI 1.4 19
  9. discuzX 数据库操作类
  10. PHP瓜分两个数组的相同元素和不同元素的两种方法
  11. 【问题解决】华硕A450C触控板失灵
  12. IE浏览器中调试各个IE版本方法
  13. knn(k近邻算法)——python
  14. 证券公司主要信用业务(融资融券、股票质押、约定购回)
  15. Windows打开文件后提示,文件或目录损坏无法读取。
  16. 边缘计算开源项目概述
  17. python爬虫时爬虫爬数据时出现“访问本页面,请开启JavaScript并刷新该页”
  18. vbox vdi磁盘注册_VirtualBox的虚拟磁盘vdi文件扩容方法
  19. Nginx + Lua 搭建网站WAF防火墙
  20. 20170925-2 功能测试

热门文章

  1. 干货:蓝海创意云制作液体教程来啦~
  2. 在线音乐播放器 --- 分页功能和其他更新
  3. 手机运存速度测试软件,开100个APP试图干掉这台12GB运存的手机,结果意外
  4. 开启10046事件的方法收集
  5. 分布式缓存Redis Cluster在华泰证券的探索与实践
  6. 基于MQTT协议的 org.eclipse.paho.client.mqttv3 源码学习(二)
  7. js(javaScript)获取当前年月日,格式(YYYY-mm-dd、YYYY年mm月dd日)
  8. 【量化投资】基于大数据量化的基本面研究探索-以酱油行业为例
  9. Vue3中slot插槽使用方式
  10. Numpy中的shape、reshape函数