MySQL学习笔记(sql执行原理、存储引擎、索引、sql优化、慢查询)

MySQL学习

1.sql的执行原理

  • Connectors

    连接、支持多种协议,各种语言

  • Management service

    系统管理和控制工具,例如:备份、集群副本管理等

  • pool

    连接池

  • sql interfaces

    sql接口-接收命令返回结果

  • parser

    分析解析器:验证

  • optimizer

    优化器:优化sql执行效率

  • cache and buffer

    查询缓存

  • storage engines

    存储引擎:可插拔

  • file system

    文件系统

1.1mysql的基本架构和执行原理

两个部分:server层与存储引擎层

  • 连接器

    建立客户端和服务器连接、权限获取、维持管理连接

    #mysql -u$user -p$password
    mysql -uroot -p

    mysql本质为客户端连接工具,tcp握手成功,需要进行身份认证

    查询连接状态:

    短链接:执行少数几次查询就会断开,浪费大量资源

    长连接:连接成功后,长时间保持连接,wait_timeout默认连接时间

    查看默认连接时长

    show variables like 'wait_timeout';

    查当前连接时长

    show processlist;

    长连接驻留内存解决方法

    1、固定时间自动重新连接

    2、mysql_reset_connection 重置连接

  • 查询缓存

    query_cache_type:查询缓存类型

    show variables like 'query_cache_type';

    如果需要使用,需要设置为DEMAND(按需)

    缓存失效

    1、增删改操作导致缓存失效

    mysql8.0已将缓存移除

  • 分析器

    词法分析:检测每个单词的含义

    语法分析:对sql语法规则校验,是否满足mysql语法规范

  • 优化器

    选择最优解

    索引选择、执行顺序可能影响执行效率,优化器进行最优选择

    select * from t1 inner join t2 using(ID) where t1.c = 10 and t2.d = 20;

    如下两个执行顺序:

    1、先找到t1.c=10的所有记录和整个t2表关联,最后筛选t2.d=20的记录

    2、先找到t2.d=20的所有记录和整个t1表关联,最后筛选t1.c=10的记录

  • 执行器

    select * from emp where no = 10;

    1、表操作权限验证

    2、innodb存储引擎查询第一行,查看no=10则写道结果集,如果不等于10则跳过

    。。。整张表查询完毕

    3、将结果返回给客户端

2.存储引擎

2.1存储引擎简介

数据库存储引擎是数据库底层软件组织,数据库管理管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。MySQL的核心就是存储引擎。

mysql底层设计采用可插拔式的存储引擎,用户根据需求,选择或自定义存储引擎

mysql5.5之后默认存储引擎为innodb

1、查看mysql可支持的存储引擎

show engines;

2、各种存储引擎对比

  • innoDB

    mysql5.5默认的存储引擎,事务型数据库。

    1.数据底层的存储:数据表文件-->>.frm(表结构)文件和.ibd(数据和索引)文件

    2.事务:支持热备份,对数据完整性要求较高,mysql是较好选择

    3.锁的粒度:采用MVVC(多版本并发)支持高并发操作,支持四种事务隔离级别,行锁

    4.存储特点:采用聚簇索引

    5.适用场景:更新和查询比较频繁,并发操作、要求事务,支持外键约束

    #查看mysql数据存储位置
    show variables like '%data%';
  • MyISAM

    1.存储形式:数据表文件-->>.frm(表结构)和.MYD和.MYI(数据和索引分离)

    2.事务:不支持

    3.存储特点:非聚簇

    4.其他:全文检索,压缩,延迟更新索引等

    5.适用场景:count计算、查询

  • Memory

    1.数据保存在内存中,增删改查效率高,但是不能持久化

    2.不支持事务、表级锁

2.2如何设置存储引擎

#默认mysql的配置文件路径
修改存储引擎:
default_storage_engine=INNODB
​
#创建表时修改存储引擎:
create table tname(col) engine = INNODB;
​
#查看某张表的基本信息
#命令行模式
show tables status from dbname where name = tname \G;

3.索引

3.1索引简介

索引:为了提升查询效率创建数据机构

3.2常见的索引模型

  • 哈希表

    键-值方式存储数据结构。使用key进行hash计算获取到一个值(位置),去该位置寻找数据(值)
    数组,hash函数 
    ​
    适用场景:
    等值查询
    不适用场景:
    范围查询,存储是无序的
    ​
    哈希碰撞(哈希冲突)
    解决方法:
    1、链表(拉链法)
    ​
    • 拉链法有序数组

    • 整个数组中排列的是有序的,查找非常方便,可以使用二分法 适用场景:等值查询、范围查询 ​ 不适用场景: 进行数据的插入与删除

      • 二叉搜索树

      二叉树结构进行数据存储
      树最影响效率的是树的深度,尽可能平衡

3.3innoDB索引模式

innodb根据主键的顺序已索引的方式进行存储。

innodb中默认采用B+树索引模型,数据组织存储到B+树中。

1、索引类型分为主键索引和非主键索引

​ 主键索引:叶子节点中存储的整行数据,称为聚簇索引。

​ 非主键索引:叶子节点中存储的是主键的值称为二级索引。

2、主键索引和非主键索引的区别

​ 主键索引只需要查找一次B+树就可以定位数据

​ 非主键索引第一次只能查找到主键的值,再根据主键的值查找到数据。

3、索引需要维护

​ 添加索引避免在增删操作较多的表

​ 索引自生也需要占用空间存储

4、索引选择

​ 优先选择主键索引

​ 主键长度越小越好

​ 尽量不要选择业务字段作为主键

​ 表的数据量较多的时候使用

​ 经可能选择高基数列(尽量唯一)

3.4添加索引

  • 查看索引

    show index from emp;
  • 普通索引

    #添加索引
    添加索引语法
    create index index_name on tname(colname);
    ​
    创建表时添加
    create table tname(
    col ...
    ....
    index index_name(colname)
    )
    ​
    #删除索引(全部)
    drop index INDEX_NAME ON tname;
  • 唯一索引

索引列必须唯一

#添加唯一索引
create unique index index_name UN_ID on tname(col);
​
#删除唯一索引
alter table tname drop index index_name;
如:
alter table stu drop index UN_ID;
  • 主键索引

特殊的唯一索引

#添加主键索引就是将唯一索引设置为主键
如:
alter table tname add constraint PK_ID primary key (id);
  • 组合索引

可以在多个字段添加索引,但是查询走索引必须使用第一个索引字段,否则不走索引
create index index_name on tname(col1,col2...);

4.sql优化

4.1使用explain分析查询

explain:查看执行计划

explain select * from stu where id = 1;

type:连接类型

ALL:表示全表扫描,若表中数据有百万至千万级别,必须要优化,否则性能很慢;
Index:full index scan,index与ALL的区别为index只遍历索引树,这通常比ALL快,因为索引文件通常比数据文件小(也就是说ALL和index都是读全表,但是index是从索引中读取的,而ALL是从硬盘中读取的)
range:只检索给定范围的行,使用一个索引来选择行,key列显示是用来那个索引,一般就是在你where语句中出现了between、<、>、in等查询,这种范围扫描比全表扫描要好,因为它只需要开始索引某一点,而结束语另一点,不用扫描全部索引。
ref:非唯一性索引扫描,返回匹配某一个单独值得所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体
eq_ref:唯一索引扫描,对于每一个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描;
const:表示通过索引一次就找到了,const用户比较primary key或者unique索引。因为只匹配一行数据,所以很快;如将逐渐置于where列表中,MySQL就能将查询转换为一个常量;
system:表示只有一行记录(等于系统表),这是const类型的特列,平时不会出现,可以忽略不计。

possiable keys:可能用到的索引

key:真正用到的索引

ley_len:索引长度,越短越好

ref:那一列被使用

row:查询的行数

4.2profiling分析语句执行时间

set profiling = on;  打开统计分析
执行查询语句后执行以下语句:
show profiles;  查看执行时间

4.3sql的基本优化原则

  • 1.字段维护在Btree上,需要对数据类型有要求(设计要求)

    • 尽可能使用较小的类型

    • 尽可能使用简单类型

    • 尽可能设置合理长度,固定长度比变化长度要快

    • not null 约束

  • 2.sql编写要求

    • 尽量不要使用select *

    • sql尽量减少嵌套

    • limit限制结果

  • 3.索引失效的状况

    • 索引列使用函数sub(),包含不要使用(会导致索引失效)

      select *from emp where id = 1; 索引
      select *from emp where id like '%1%'; 全表
    • 索引列不要用于计算

      select * from emp where sal *0.9 = 1000; 索引失效
      select * from emp where sal  = 1000/0.9; 索引有效
    • 索引列不要使用(!= <>)

      select * from emp where no <> 10; 全表
      ​
      select * from emp where no > 10 
      union 
      select * from emp where no < 10;  索引
    • in和exists

      in 把内表和外表进行hash连接,exists把外表loop
      内表和外表数据量差距不大,性能基本相同
      内表数据量小使用in,外表数据量小使用exists

5.慢查询

开启慢查询日志,MySQL记录执行阶段影响性能的sql信息,定位分析系统的瓶颈

5.1慢查询的参数

#查看慢查询是否开启及慢查询日志位置
show variables like 'slow';
#查看慢查询的时间长度(超过多长时间就是慢查询)
show variables like 'long_query';

5.2设置慢查询

  • 开启慢查询(命令开启,重启数据库后会失效)

#开启慢查询
set global show_query_log=on;
  • 设置配置文件开启(重启MySQL服务后生效)

#/etc/my.cnf 
[mysqld]
slow_query_log_file=/var/log/mysql/slow.log  :注意修改权限使之可以读写777
slow_query_log = ON
long_query_time=1
  • 查看执行慢查询的次数

show global status like '%slow_queries%';
  • 慢查询分析工具

    • mysqlduampslow(内置慢查询分析工具)

    mysqlduampslow /var/log/mysql/slow.log
    • pt-query-digest(第三方分析工具)

    pt-query-digest /var/log/mysql/slow.log

猜你喜欢

转载自blog.csdn.net/u012002125/article/details/103230631