在正式介绍Mysql调优之前,先补充mysql的两种引擎

mysql逻辑分层

InnoDB:事务优先(适合高并发操作,行锁)

MyISAM:性能优先(表锁)

查看使用的引擎:

  1. show variables like "%storage_engine%";

使用哪个引擎在创建表时通过Engine=InnoDB创建,下面正式开始


一、为什么要对sql进行优化:

有时候数据库会出现性能低、执行时间太长、等待时间太长、SQL语句欠佳(连接查询)、索引失效等问题,这些问题会严重拖慢一个系统的速度,因此需要对sql进行优化。

SQL的编写过程和解析过程并非是一致的,下面是两者执行的先后顺序:

    1. 编写过程:
      1. select..from..join..on..where..group by...having..order by...limit.
        1. 解析过程:
          1. from..on..join..where..group by....having...select..order by...limit..
        1.  

        二、SQL如何优化:

        SQL优化,主要就是在优化索引

        索引:相当于书的目录,是帮助MYSQL高效获取数据的数据结构。就好比我们查字典,如果没有目录查一个字就需要遍历整本字典,而有了目录之后只需要按目录查询。索引的数据结构有(树:B+树(默认)、Hash树等等)

        B+树是一种数据结构,所有的元素全部放在叶子节点,因此B+树查询数据都需要n次,n与树的高度相同

        2.1、索引的弊端:

        1.索引本身很大,需要存放在内存/硬盘(通常为硬盘)

        2.索引不是所有情况均适用,以下三种情况不适合用索引:

        a.少量数据

        b.频繁更新的字段

        c.很少使用的字段

        3.索引提高了查询速度,但是会降低增删改的效率

        2.2 索引的优势:

        1.提高查询效率(降低IO使用率)

        2.降低CPU使用率

        2.3 关于索引的分类:

        单值索引:单列的索引,比如学生表中的grade。一个表可以有多个单值索引

        唯一索引:与单值索引的区别是属性不能重复。比如主键id

        主键索引:与唯一索引的区别是内容不能为null

        复合索引:多个列构成的索引,(name,grade)构成索引后先查name,再查grade

        2.4 如何创建索引:

        方法一:

        create 索引类型 索引名 on 表(字段)

          1. 单值索引:
            1. create index name_index on student(name);
              1. 唯一索引:
                1. create unique index id_index on student(id);
                  1. 复合索引:
                    1. create index name_grade_index on student(name,grade);
                  1.  

                  方法二:

                  alter table 表名 add 索引类型 索引名(字段);

                    1. 单值索引:
                      1. alter table student add index name_index(name);
                        1. 唯一索引:
                          1. alter table student add unique index id_index(id);
                            1. 复合索引:
                              1. alter table student add index name_grade_index(name,grade);
                            1.  

                            删除索引:

                            1. drop index 索引名 on 表名

                            2.5 explain关键字

                            通过explain关键字可以看到sql语句的执行过程,其中type、key、key_len、Extra需要尤其注重

                            id:标识符

                            如果有多个id,id值相同,顺序执行;id值不同,id值越大越优先查询

                            select_type:查询类型

                            primary:包含子查询SQL中的主查询(最外层)

                            subquery:包含子查询SQL中的子查询(非最外层)

                            simple:简单查询(不包含子查询、union)

                            derived:衍生查询(使用到了临时表)

                            union:当查询时用到了table1 union table2,table1类型是derived,table2的类型是union

                            union result:哪些表存在union查询

                            table:查询的是哪张表

                            type:索引类型

                            system>const>eq_ref>ref>range>index>all

                            system>const存在于理想状态,实际能达到ref,索引的优化一般到ref为止

                            const:仅仅能查到一条数据的SQL,用于主键索引和唯一索引

                            eq_ref:唯一性索引:对于每个索引键的查询,返回匹配唯一行数据(有且只有1个,不能多、不能0)

                            ref:非唯一性索引,对于每个索引键的查询,返回匹配的所有行

                            range:检索指定范围的行,where后面是一个范围查询(between,>,<)等。

                            index:查询全部索引中的数据

                            all:查询全部表中的数据

                            possible_keys 可能用到的索引

                            key实际用到的索引

                            key_len:索引的长度,用于判断复合索引是否被完全使用

                            ref:指明当前表所参照的字段

                            rows:被索引优化查询的数据个数(实际通过索引查询到的数据个数)

                            Extra

                            using filesort:性能消耗大;需要“额外”的一次排序,常见于orderby语句

                            using temporary:性能损耗大,用到了临时表,一般出现在groupby中

                            using index:性能提升;索引覆盖(覆盖索引)。原因:不读取原文件,只从索引文件中获取数据

                            using where:回表查询;

                            三、索引优化实例:

                            建一张book表,插入一些数据

                              1. create table book
                                1. (
                                  1. bid int(4) primary key,
                                    1. name varchar(20) not null,
                                      1. authorid int(4) not null,
                                        1. typeid int(4) not null
                                          1. );
                                            1. insert into book values(1,'java',1,1);
                                              1. insert into book values(2,'c',2,2);
                                                1. insert into book values(3,'math',3,3);
                                                  1. insert into book values(4,'english',4,3);
                                                1.  

                                                首先不建立索引查看查询情况:虽然我没建立索引,但是mysql5.7自动建立了主键索引,现在的type是index,继续优化:

                                                添加一个复合索引,将查询时所用到的属性均加入进去

                                                1. alter table book index a_t_b(authorid,typeid,bid);

                                                 此时的type已经到了ref,达到了最好的优化效果,在额外信息中依旧存在using where,因为当使用in时,部分索引可能会失效,所以一部分数据从索引中查询,一部分数据回表查询。

                                                四、加索引的技巧:

                                                1、小表驱动大表:

                                                select ... from .... where 小表.x=大表.x;

                                                2、索引建立在经常使用的字段上

                                                3、exist和in:

                                                如果主查询的数据集大,则使用in,如果子查询的数据集大,则使用exist

                                                1. select .. from table where exist/in (子查询)

                                                4、order by优化:

                                                1.避免select *的使用

                                                2.复合索引不要跨列使用

                                                3.保证所有排序字段排序顺序的一致性(都是升序或降序)

                                                五、避免索引失效的原则

                                                1、复合索引不要跨列或无序使用(最佳左前缀):索引的顺序和sql语句查询时的顺序一致

                                                2、复合索引尽量使用全索引匹配

                                                3、不要在索引上进行任何操作(计算、函数、类型转换)

                                                4、like尽量以“常量”开头,不要以%开头,否则索引失效

                                                5、尽量不要使用类型转换(显示、隐式),否则索引失效,如:

                                                  1. name的属性是varchar,这里变成了int
                                                    1. select * from teacher where name=123
                                                  1.  

                                                  6、 尽量不要使用or,否则索引失效

                                                  六、慢查询日志的使用

                                                  慢查询日志是mysql提供的一种日志记录,用于记录Mysql响应时间超过阈值的Sql语句(long_query_time,默认10秒)。

                                                  慢查询日志默认是关闭的,建议开发时开启,部署时关闭

                                                    1. 查看慢查询日志
                                                      1. show variables like '%slow_query_log%';
                                                    1.  

                                                    临时开启慢查询日志

                                                    1. set global slow_query_log=1;

                                                    永久开启:在mysql的配置文件里增加下面两句话:

                                                      1. slow_query_log=1
                                                        1. slow_query_log_file=XXX/slow.log
                                                      1.  

                                                      查看慢查询时间阈值:

                                                      1. show variables like '%long_query_time%';

                                                      更改慢查询时间阈值

                                                      1. show variables like '%long_query_time%';

                                                      Mysql的索引调优详解:如何去创建索引以及避免索引失效的更多相关文章

                                                      1. Spark Streaming性能调优详解

                                                        Spark Streaming性能调优详解 Spark  2015-04-28 7:43:05  7896℃  0评论 分享到微博   下载为PDF 2014 Spark亚太峰会会议资料下载.< ...

                                                      2. Spark Streaming性能调优详解(转)

                                                        原文链接:Spark Streaming性能调优详解 Spark Streaming提供了高效便捷的流式处理模式,但是在有些场景下,使用默认的配置达不到最优,甚至无法实时处理来自外部的数据,这时候我们 ...

                                                      3. JVM性能调优详解

                                                        前面我们学习了整个JVM系列,最终目标的不仅仅是了解JVM的基础知识,也是为了进行JVM性能调优做准备.这篇文章带领大家学习JVM性能调优的知识. 性能调优 性能调优包含多个层次,比如:架构调优.代码 ...

                                                      4. [转帖]JVM性能调优详解

                                                        JVM性能调优详解 https://www.cnblogs.com/secbro/p/11833651.html 应该是 jdk8 以前的方法 貌似permsize 已经放弃这一块了. 前面我们学习了 ...

                                                      5. Java生产环境下性能监控与调优详解视频教程 百度云 网盘

                                                        集数合计:9章Java视频教程详情描述:A0193<Java生产环境下性能监控与调优详解视频教程>软件开发只是第一步,上线后的性能监控与调优才是更为重要的一步本课程将为你讲解如何在生产环境 ...

                                                      6. Mysql运行状态查询命令及调优详解

                                                        (转载自点击打开链接) MySQL运行状态及调优(一) 一.查看MySQL运行情况SHOW STATUS; 二.查看INNODB数据库引擎运行状态SHOW ENGINE INNODB STATUS; ...

                                                      7. Java生产环境下性能监控与调优详解

                                                        1:JVM字节码指令与 javapjavap <options> <classes>cd monitor_tuning/target/classes/org/alanhou/m ...

                                                      8. Tomcat调优详解

                                                        前言 在这里告诫一下那些感觉自己啥都会的朋友们,其实你会的可能只是皮毛,不要感觉这个东西以前已经做过了,就不想去做了 其实你还远没有达到精通的地步,遇到以前做过的东西,也要用心的再去做一遍,你可能会从 ...

                                                      9. 7.JVM调优-方法区,堆,栈调优详解

                                                        通常我们都知道在堆空间新生代Eden区满了,会触发minor GC, 在老年代满了会触发full GC, 触发full GC会导致Stop The World, 那你们知道还有一个区域满了一会触发Fu ...

                                                      随机推荐

                                                      1. 【Azure 存储服务】代码版 Azure Storage Blob 生成 SAS (Shared Access Signature: 共享访问签名)

                                                        问题描述 在使用Azure存储服务,为了有效的保护Storage的Access Keys.可以使用另一种授权方式访问资源(Shared Access Signature: 共享访问签名), 它的好处可 ...

                                                      2. RedHat 7.0 下 FTP 服务的安装,启动,配置,以及虚拟用户的建立

                                                        (注意! 区分shell命令和往配置文件里加的代码不同) 一:ftp服务的安装,启动和启用.   1:vim /etc/sysconfig/selinux     改为disabled后重启     ...

                                                      3. Linux&c 文件操作,线程进程控制,网络编程,简单知识点梳理

                                                        一:文件操作 在linux下,一切皆文件,目录是文件,称为目录文件,内容是该目录的目录项(但是目录只有内核可以编辑,超级用户也不可以编辑),设备也是设备文件,在/dev存放的就是一些设备文件,linu ...

                                                      4. 【python】使用python十分钟创建个人聊天机器人教程

                                                        以青云客和图灵机器人接口示范python创建个人聊天机器人教程 一.以青云客聊天机器人为例示范get请求 官方网址:http://api.qingyunke.com/ 1.接入指引 请求地址 http ...

                                                      5. idea查看方法在哪里被调用

                                                        方法一 选中方法名,右键选择Find Usages 方法二 选中方法快捷键ctrl + alt + h查看Hierarchy Callers

                                                      6. HttpClient用法--这一篇全了解(内含例子)

                                                        HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也 ...

                                                      7. 在同级路径下,SpringBoot两种类型的配置文件(.properties/.yml)同时存在时,配置优先级如何处理?

                                                        两类配置文件如果同时存在,若 key 相同则 properties 优先级高,若key不同则合并加载:

                                                      8. Part 61 to 63 Talking about partial class and partial method in C#

                                                        部分类和部分方法 部分类是用partial声明的类,它允许我们把一个类分割成两个或多个类,当应用程序编译的完成的时候,多个部分类会结合成一个类,同时partial关键字也可以用于声明结构和接口. 那么 ...

                                                      9. Linux下搭建FFmpeg开发调试环境

                                                        背景 如果你是一个FFmpeg的使用者,那么绝大部分情况下只需要在你的程序中引用FFmpeg的libav*相关的头文件,然后在编译阶段链接相关的库即可.但是如果你想调试FFmpeg内部相关的逻辑,或者 ...

                                                      10. thinkphp5 目录结构

                                                        /*    ├─application           应用目录    │  ├─common             公共模块目录(可以更改)    │  ├─module_name       ...