• MySql索引及索引优化


    继弄清楚索引底层基础架构之后,我们知道索引是帮助高效查询数据的数据结构,要写出高效查询的SQL语句,就要用到索引,以及我们要调优语句,这里就不得不说到执行计划explain。

    首先我们来了解一下SQL的解析顺序,通过具体机制,我们知道,执行大致顺序是 from...on...join...where ...group by...having...select...order by...limit...,与我们编写顺序截然不同,通过了解执行顺序,我们就能更明确知道索引应当如何正确的编写。

    一、explain释义

     mysql官网,给出了explain每个字段的意义,这里我就不再详细说明,主要对索引优化的时候,我们需要着重关注的几个关键字是:type,possible_keys,key,key_len,Extra。

    Extra释义:不在其他列显示的额外信息。

    1. using index,当前列使用索引,从衍生表中查询信息没有进行额外的去查询实际行,这种策略可被用在列是索引的一部分。
    2. using where,where从句中限定的行在其他表中相匹配,也就是需要回表查询。
    3. using tempporary,用到了临时表,一般在groupby或orderby的语句中。
    4. using filesort,需要额外的一次查找或排序,性能消耗最大。
    5. using join buff,读取数据在关联查询的时候,需要用到join缓存。

    从extra的意思来看,当using index的时候,我们的查询语句命中索引,给我们的查询带来性能提升,有效的节约时间。而最糟糕的using filesort还需要一次额外的查找,导致性能损耗较大。

    虽然索引,存在一些弊端,譬如:占用空间大,降低命令执行效率。但我们索引不仅降低了IO消耗,提升查询效率,还降低CPU使用率,使得排序简单,所以我们应当在查询时候,使用using index。

    二、优化细则

    从Mysql的索引底层原理我们知道,聚集索引和非聚集索引是由于存储引擎的差异,出现不同的效果。在索引类型中,存在着常见的几种索引类型:普通索引(index)、唯一索引(unique)、主键索引(primary key)、复合索引。其中主键索引是唯一索引,且要求主键不为NULL,复合索引中,以最佳左前缀规格,不可以跨列等要求。下面以实际的例子来演示细节。

    1. 为查询加索引

     当我们没有对student加上索引的时候,type为ALL,也就是进行全表扫描。

    现在,我们给student主键加上索引,同时进行限定查询,可以用上了type=ref级别的索引。—— 总结:建立索引。

    创建name和age列的组合索引,从第二条SQL语句可以看出,跨列查询,导致索引失效。—— 总结:组合索引不要跨列,尽量使用覆盖索引。

    在索引列name上,进行任何运算,会导致无法树节点值无法命中索引,从而使索引失效。—— 总结:索引列上作运算会导致索引列失效。

     对于范围查询的<>和!=,也是导致无法命中索引点,进行全表扫描,我们可以用 > < 进行替代。——总结:范围查询中不等于导致索引失效。

     like查询的时候,我们有时候也不得不使用左右模糊匹配,可以尝试用es等服务,进行匹配优化。——总结:Like以通配符开头会导致索引失效。

     索引匹配使用or无法命中索引。——总结:少用or,会导致索引失效。 

    2. 为排序加索引;

    Mysql的有两种排序方式,文件排序(using filesort)和扫描有序索引排序,Mysql能为排序和查询使用相同的索引。在Orderby的时候,以最佳左前缀匹配或常量为关键点,则Orderby能够使用索引。如下,三条sql均使用索引s_n_g。—— 总结:最佳左前缀或者常量匹配,则使用索引。

    根据最佳左前缀原则,跨节点,排序顺序不一致,或者无关索引字段排序,都会导致一次额外的查询,即using filesort;其实这里有个概念即单路排序和双路排序。双路排序即进行两次IO,导致性能下降。在MySql4.1之后,开始使用单路排序,但是如果一次性取出的数据比较多,超过了sort_buffer存储上限,就会变成变成多路。

    ——总结:加大sort_buffer的值,且不要用select *

     group by 则是先排序后分组,基本规则与orderby一置。

    3. 多表关联优化;

    其实根据我们的数据计算算放,对于3*4*5和5*4*3的结果是一样,但是以3*4的出来的数据仅仅只有12行,而5*4有20行,再进行关联匹配的时候,后者将会循环的次数变多。——总结:小表驱动大表。

    explain索引优化仅是查询优化第一环,在MySql的设置中可以开启慢查询日志,记录慢查询SQL语句并进行分析。这次索引优化总结如下:

    附录:

    --学生表
    create table student(
    id int not null auto_increment,
    name varchar(50) not null default '',
    gender char(1) not null default '0',
    primary key(id));
    --课程表
    create table course(
    id int not null auto_increment,
    name varchar(50) not null default '',
    primary key(id));
    --选课表
    create table course_c(
    id int not null auto_increment,
    studentid int not null default 0,
    courseid int not null default 0,
    primary key(id));
    建表语句
    insert into student(name,gender) values('zhangsan','1');
    insert into student(name,gender) values('lisi','0');
    insert into student(name,gender) values('wangwu','1');
    insert into student(name,gender) values('zhaoliu','0');
    
    insert into course(name) values('C++');
    insert into course(name) values('C#');
    insert into course(name) values('JAVA');
    
    insert into course_c(studentid,courseid) values(1,2);
    insert into course_c(studentid,courseid) values(2,3);
    insert into course_c(studentid,courseid) values(1,3);
    insert into course_c(studentid,courseid) values(3,1);
    insert into course_c(studentid,courseid) values(3,3);
    insert into course_c(studentid,courseid) values(3,2);
    预插数据

      

  • 相关阅读:
    select SCOPE_IDENTITY()用法
    SQL 2005 with(nolock)详解
    .NET4进行COM互操作导出数据到Excel
    Counterfeit Dollar 1013 pku
    Numbers that count 1016 PKU
    对局问题 ——取火柴问题(转)
    (a^b) mod c
    对局问题——放硬币问题(转)
    对局问题 ——取石子问题– 1堆(转)
    Follow My Logic 1048 PKU
  • 原文地址:https://www.cnblogs.com/weilai1917/p/12418908.html
Copyright © 2020-2023  润新知