查询优化本就不是一蹴而就的,需要学会使用对应的工具、借鉴别人的经验来对SQL进行优化,并且提升自己。

分享一套博主觉得讲的很详细很实用的MySQL教程给大家,可直接点击观看!

https://www.bilibili.com/video/BV1fx411X7BD

先来巩固一下索引的优点,检索数据快、查询稳定、存储具有顺序性避免服务器建立临时表、将随机的I/O变为有序的I/O。

但索引一旦创建的不规范就会造成以下问题,占用额外空间,浪费内存,降低数据的增、删、改性能。

所以只有在理解索引数据结构的基础上才能创建出高效的索引。

**本文所有操作均在MySQL8.0.12**

一、创建索引规范

在学习索引优化之前,需要对创建索引的规范有一定的了解,此规范来自于阿里巴巴开发手册。

  • 主键索引:pk_column_column
  • 唯一索引:uk_column_column
  • 普通索引:idx_column_column

二、索引失效原因

创建索引需知道在什么情况下索引会失效,只有了解索引失效的原因,在创建索引时才不会出现一些已知错误。

1.带头大哥不能死

这局经典的语句就是涵盖创建索引时一定要符合最左侧原则。

例如表结构为u_id,u_name,u_age,u_sex,u_phone,u_time

创建索引为idx_user_name_age_sex。

查询条件必须带上u_name这一列。

2.不在索引列上做任何操作

不在索引列上做任何计算、函数、自动或者手动的类型转换,否则会进行全表扫描。简而言之不要在索引列上做任何操作。

3.俩边类型不等

例如建立了索引idx_user_name,name字段类型为varchar

在查询时使用where name = kaka,这样的查询方式会直接造成索引失效。

正确的用法为where name = “kaka”。

4.不适当的like查询会导致索引失效

创建索引为idx_user_name

执行语句为select * from user where name like “kaka%”;可以命中索引。

执行语句为select name from user where name like “%kaka”;可以使用到索引(仅在8.0以上版本)。

执行语句为select * from user where name like ‘’%kaka";会直接导致索引失效

5.范围条件之后的索引会失效

创建索引为idx_user_name_age_sex

执行语句select * from user where name = ‘kaka’ and age > 11 and sex = 1;

上面这条sql语句只会命中name和age索引,sex索引会失效。

复合索引失效需要查看key_len的长度即可。

总结:%在后边会命令索引,当使用了覆盖索引时任何查询方式都可命中索引。

以上就是关于索引失效会出现的原因总结,在很多文章中没有标注MySQL版本,所以你有可能会看到is null 、or索引会失效的结论。

三、SQL优化杀手锏之Explain

在写完SQL语句之后必须要做的一件事情就是使用Explain进行SQL语句检测,看是否命中索引。

下图就是使用explain输出格式,接下来将会对输出格式进行简单的解释。

1.id

这列就是查询的编号,如果查询语句中没有子查询或者联合查询这个标识就一直是1。

如存在子查询或者联合查询这个编号会自增。

2.select_type

最常见的类型就是SIMPLE和PRIMARY,此列知道就行了。

3.table

理解为表名即可

4.**type

此列是在优化SQL语句时最需要关注的列之一,此列显示了查询使用了何种类型。

以下排序从最优到最差。

  • system:表内只有一行数据
  • const:最多只会有一条记录匹配,常用于主键或者唯一索引为条件查询
  • eq_ref:当连接使用的索引为主键和唯一时会出现
  • ref:使用普通索引=或<=> 运算符进行比较将会出现
  • fulltext:使用全文索引
  • ref_or_null:跟ref类型类似,只是增加了null值的判断,实际用的不多。语句为where name = ‘kaka’ and name is null,name为普通索引。
  • index_merge:查询语句使用了俩个以上的索引,常见在使用and、or会出现,官方文档将此类型放在ref_or_null之后,但是在很多的情况下由于读取索引过多性能有可能还不如range
  • unique_subquery:用于where中的in查询,完全替换子查询,效率更高。语句为value IN (SELECT primary_key FROM single_table WHERE some_expr)
  • index_subquery:子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引
  • range:索引范围查询,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中。
  • index:索引全表扫描,把索引从头到尾扫一遍
  • all:全表扫描,性能最差。

5.possible_keys

此列显示的可能会使用到的索引

6.**key

优化器从possible_keys中命中的索引

7.key_len

查询用到的索引长度(字节数),key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。

8.ref

如果是使用的常数等值查询,这里会显示const。

如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段。

如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func。

9.**rows

这是mysql估算的需要扫描的行数(不是精确值)。

这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好。

10.filtered

此列表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数

11.**extra

在大多数情况下会出现以下几种情况。

  • Using index:使用了覆盖索引,查询列都为索引字段
  • Using where:使用了where语句
  • Using temporary :查询结果进行排序的时候使用了一张临时表
  • Using filesort :对数据使用一个外部的索引排序
  • Using index condition:使用了索引下推,关于索引下推可以查看之前文章MySQL索引一文

12.总结

以上就是关于Explain所有列的说明,在平时开发的过程中,一般只会关注type、key、rows、extra这四列。

  • type优化目标至少达到range级别,要求是ref级别,如果可以consts最好。
  • key是查询使用到的索引,如果此列为空,要么未建立索引,要么索引失效。
  • rows是这条SQL语句扫描的行数,越少越好。
  • extra:此列为扩展列,如果出现临时表、文件排序则需要优化。

四、SQL优化杀手锏之慢查询

上文说到了可以直接使用explain来分析自己的SQL语句是否合理,接下来再聊一个点那就是慢查询。

查看慢查询是否打开

查看是否记录没有使用索引的SQL语句

开启慢查询、开启记录没有使用到索引的SQL语句

set global log_queries_not_using_idnexes=‘on’;

set global log_queries_not_using_indexes=‘on’;

查询以上俩个配置是否打开

设置慢查询时间,这个时间由自己把控,一般1s即可set globle long_query_time=1;

如果查看这个时间没有变,则关于客户端在重新连接一次即可。

查看慢查询存储位置

然后随便执行一条不执行索引的语句即可在这个日志中查看到此语句

上图中一般需要主要观察的是Query_time、SQL语句内容。

以上就是关于如何使用慢查询来查看项目中出现问题的SQL语句。

五、优化大法

此处跟大家聊一些常用的SQL语句优化方案,以上的俩个工具要好好的利用,辅助我们进行打怪。

  • 禁止使用select *,需要什么字段查询什么字段
  • where字段设置索引
  • group by、order by字段设置索引
  • 舍弃offset,limit分页,使用延迟关联来实现分页(数据量不大时可不用)
  • 写分页时当count为0时,直接返回避免执行分页语句
  • 利用覆盖索引进行查询避免回表
  • 建立复合索引时区分度最高的放在最左侧
  • 统计数据行数只用count(*),别整的花里胡哨的
  • 关于in和exist,如果查询的俩个表大小一致则性能差别可忽略,如果子查询表大用exist,否则使用in
  • 查询一行数据时加上limit 1
  • 选择合理的数据类型,在满足条件下数据类型越小越好
  • 联合查询join最多三个表,并且需要join的字段数据类型保持一致
  • in操作能避免尽量避免,无法避免的情况下in元素控制在1000以内
  • 数据更新频繁,区分度不高的列不适合建立索引
  • explain中的type至少要达到range,要求为ref
  • 联合索引满足最左侧原则

一文带你掌握MySQL查询优化技能的更多相关文章

  1. JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!

    序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...

  2. Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析

    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析     Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...

  3. Mysql查询优化器

    Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...

  4. Mysql查询优化器浅析

    --Mysql查询优化器浅析 -----------------------------2014/06/11 1 定义    Mysql查询优化器的工作是为查询语句选择合适的执行路径.查询优化器的代码 ...

  5. MySQL查询优化(转)

    在分析性能欠佳的查询时,应考虑: 1) 应用程序是否正获取超过需要的数据,即访问了过多的行或列. 2) Mysql服务器是否分析了超过需要的行. 如果发现访问的数据行数很大,而生成的结果中数据行很少, ...

  6. MYSQL查询优化:使用索引

    索引是提高查询速度的最重要的工具.当然还有其它的一些技术可供使用,但是一 般来说引起最大性能差异的都是索引的正确使用.在MySQL邮件列表中,人们经常询问那些让查询运行得更快的方法.在大多数情况下,我 ...

  7. MySQL 查询优化之 Multi-Range Read

    MySQL 查询优化之 Multi-Range Read MRR的工作原理 MRR开启与关闭 使用MRR示例 参考文档 在存储引擎中未缓存的大表,使用辅助索引的range scan检索数据, 可能会导 ...

  8. MySQL 查询优化之 Index Merge

    MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...

  9. 一文带你了解elasticsearch

    一文带你了解elasticsearch cxf2102100人评论160人阅读2019-07-02 21:31:36   elasticsearch es基本概念 es术语介绍 文档Document ...

随机推荐

  1. Docker搭建Hadoop环境

    文章目录 Docker搭建Hadoop环境 Docker的安装与使用 拉取镜像 克隆配置脚本 创建网桥 执行脚本 Docker命令补充 更换镜像源 安装vim 启动Hadoop 测试Word Coun ...

  2. VMware 安装 CentOS7 后的简单配置

    1.连网 如果能连网,跳过此步 试着ping一下百度 ping baidu.com 动态分配 IP sudo vim /etc/sysconfig/network-scripts/ifcfg-ens3 ...

  3. Caffe介绍与测试及相关Hi35xx平台下caffe yolox的使用参考

    这一篇我大概讲讲Caffe框架下MNIST的实现与基于Hi35xx平台下caffe yolox的运用等,供大家参考 1.Caffe介绍与测试 caffe全称Caffe Convolutional Ar ...

  4. 第01章-Java SE8的流库

    从迭代到流的操作 流表面上看起来和集合很类似,都可以让我们转换和获取数据,但是它们之间存在着显著的差异 流并不存储其元素,这些元素可能存储在底层的集合中,或者是按需生成的 流的操作不会修改其数据源 流 ...

  5. Excel查分系统搭建小技巧

    推荐一个教师必备工具"Yichafen",是一个在线查分系统,全国8000所高校都在用,三分钟极速创建发布查分系统 在工作学习中,我们经常会遇到查分系统这样的问题.培根说过:读书足 ...

  6. go中sync.Cond源码解读

    sync.Cond 前言 什么是sync.Cond 看下源码 Wait Signal Broadcast 总结 sync.Cond 前言 本次的代码是基于go version go1.13.15 da ...

  7. 前端笔记:React的form表单全部置空或者某个操作框置空的做法

    1.全部置空的做法,一般在弹出框关闭后,需要重置该form所有表单: this.props.form.resetFields(); 2.针对某个操作框置空的做法 例如,form表单里有一个部门和一个张 ...

  8. NoSQL安装与操作

    redis操作: redis的启动与关闭:注意:(需要关闭防火墙) redis的启动:redis-server redis.conf redis的登录:redis-cli -a pass redis的 ...

  9. golang 二维平面求多重遮挡三角形总面积

    解决问题描述:二维平面有很多三角形错落,可能会相互叠加落在一起,也可能互相远离.目标求出这些三角形的总占地面积. 我最开始想的解决方案是用总面积-总重叠面积 = 总占地面积.后来实现起来发现当面临多次 ...

  10. QT项目-Chart Themes Example学习(一)

    1.main.cpp #include "themewidget.h" #include <QtWidgets/QApplication> #include <Q ...