MySQL学习

文章目录

  • 前言
  • MySQL架构
  • 存储引擎
    • 1.语法
    • 2.存储引擎特点
      • innoDB
        • 逻辑存储结构:
      • MyISAM
      • Memory
      • 存储引擎对比
    • 3.存储引擎选择
  • 索引
    • 1.索引结构
      • B+Tree
      • Hash
      • 为什么innoDB存储引擎选择B+Tree索引结构?
    • 2.索引的分类
    • 3.索引语法
      • 查看数据库增删改查情况
    • 索引优缺点
  • SQL性能分析
    • 慢查询日志
    • profile详情
    • explain执行计划
      • explain执行计划各字段含义
    • 索引的使用
    • 索引的设计原则
  • SQL优化
    • 插入优化
    • 主键优化
      • 主键设计原则
    • order by优化
      • order by优化方法
    • limit优化
    • count优化
      • count的几种用法
  • todo未完待续
  • 总结
  • Q&A


前言

        作为一个程序猿,平时经常使用数据库,虽然说可以熟练使用数据库,但是对数据库的一些内部原理调优了解不太全面。本文以MySQL为例子,学习数据库的简单原理和一些调优。
        在此特别感谢黑马MySQL学习视频。


MySQL架构

MySQL学习_第1张图片

存储引擎

1.语法

#查看存储引擎
show engines;
#创建sql指定存储引擎
create table xxx (...) engine=innodb;

2.存储引擎特点

innoDB

        innoDB是一种兼顾高可靠性和高性能的通用存储引擎,在MySQL5.5之后,innoDB是默认存储引擎。

特点:

  1. DML操作遵循ACID模型,支持事务
  2. 行级锁,提高并发访问性能;
  3. 支持外键FOREIGN KEY约束,保证数据的完整性和正确性。

文件:
        xxx.ibd:xxx代表的是表名,innoDB引擎的每张表都会对应这样一个表空间文件,存储该表的表结构(frm、sdi)、数据和索引。
参数:innodb_file_per_table;

逻辑存储结构:

MySQL学习_第2张图片

MyISAM

        MyISAM是mysql早期的默认存储引擎。

特点:

  1. 不支持事务,不支持外键;
  2. 支持表锁,不支持行锁;
  3. 访问速度快;

文件:
xxx.sdi:存储表结构信息;
xxx.MYD:存储数据;
xxx.MYI:存储索引;

Memory

        Memory引擎的表数据是存储在内存中的,由于受到硬件问题或者断电问题的影响,只能将这些表作为临时表或缓存使用。

特点:

  1. 内存存放;
  2. hash索引;
  3. 速度快;

文件:
xxx.sdi:存储表结构信息;

存储引擎对比

MySQL学习_第3张图片
MySQL学习_第4张图片

3.存储引擎选择

        在选择存储引擎的时候,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。

  • innoDB:是MySQL的默认存储引擎,支持事务、外键和行级锁。如果应用对事物的完整性有较高的要求,在并发条件下要求数据一致性,数据操作除了插入和查询之外,还包含很多更新、删除操作,那么innoDB存储引擎是比较合适的选择;
  • MyISAM:如果应用是以读操作为主,只有很少的更新和删除,并且对事物的完整性、并发性要求不是很高,可以选择它;
  • MEMORY:将所有的数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺点就是对于表的大小有限制,太大的表无法缓存在内存中。

索引

1.索引结构

B+Tree

        MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
MySQL学习_第5张图片

Hash

       哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
       如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称hash碰撞),可以通过链表来解决。
MySQL学习_第6张图片
特点:

  1. hash索引只能用于对等比较(=,in)不支持范围查询(between,>,<,>=,<=);
  2. 无法利用索引完成排序操作;
  3. 查询效率高,通常只需要一次检索就可以了,效率通常高于B+Tree索引;

为什么innoDB存储引擎选择B+Tree索引结构?

  1. 相对于二叉树,层级少,搜索效率高
  2. 对于B-Tree,无论是叶子结点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
  3. 对于hash索引,B+Tree支持范围匹配及排序操作

2.索引的分类

分类 含义 特点 关键字
主键索引 针对于表中主键创建的索引 默认自动创建,只能有一个 PRIMARY
唯一索引 避免同一个表中某数据列中的值重复 可以有多个 UNIQUE
常规索引 快速定位特定数据 可以有多个
全文索引 全文索引查找的是文本中的关键词,而不是比较索引中的值 可以有多个 FULLTEXT

在innoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:

分类 含义 特点
聚集索引(clustered index) 将数据存储与索引放到一块,索引结构的叶子节点保存了行数据 必须有,而且自有一个
二级索引(secondary index) 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 可以存多个

聚集索引选取规则:

  1. 如果存在主键,主键索引就是聚集索引;
  2. 如果不存在主键,将使用第一个唯一索引(unique)作为聚集索引;
  3. 如果表没有主键,或没有合适的唯一索引,则innoDB会自动生成一个row作为隐藏的聚集索引;
    MySQL学习_第7张图片
    回表查询:
    MySQL学习_第8张图片

3.索引语法

创建索引:

create [unique|fulltext] index index_name on table_name

查看索引:

show index from table_name

删除索引:

drop index index_name on table_name

查看数据库增删改查情况

show global status like 'Com_________'

索引优缺点

优点 缺点
提高数据检索的效率,降低数据库的IO成本 索引列也要占用空间
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗 索引大大提高查询效率,同时也降低增删改的效率

SQL性能分析

慢查询日志

        慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。MySQL的慢查日志默认是没有开启的,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:

#开启MySQL慢查日志查询开关
slow_query_log=1
#设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2

        配置完毕后,通过以下指令重启MySQL服务器进行测试,查看慢日志文件中的记录的信息 /var/lib/mysql/localhost-slow.log。

        查看慢查询是否打开。

show variables like 'slow_query_log';

profile详情

        show profiles 能够在做SQL优化时帮助我们了解时间都消耗到哪里去了。通过have_profiling参数,能够看到当前MySQL是否支持profiles操作。

select @@have_profiling;

        默认profiling是关闭的,可以通过set语句在session/global级别开启profiling:

set profiling = 1;

explain执行计划

explain或者desc命令获取MySQL如何执行select语句的信息,包括在select语句执行过程中表如何连接和连接顺序。语法:

#直接在select语句之前加上关键字explain或者desc
explain SELECT cloumns_list FROM table_name WHERE query_condition

explain执行计划各字段含义

  • id
    select查询的序列号,表示查询中执行select子句或者操作表的顺序(id相同,执行从上到下,id不同,值越大,越先执行)。
  • select_type
    select的类型,常见的取值有SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(select/where之后包含了子查询)等。
  • type
    表示连接类型,性能由好到差的连接类型为,null、system、const、eq_ref、ref、range、index、all
  • possible_key
    显示可能应用在这个查询中的索引,一个或者多个。
  • key
    实际使用的索引,如果null,则没有使用索引。
  • key_len
    表示索引中使用的字段数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精度的前提下,长度越短约好。
  • rows
    MySQL认为必须要执行查询的行数,在innoDB引擎的表中,是一个估计值,可能并不总是准确的。
  • filtered
    表示返回结果的行数占需读取行数的百分比,filtered的值越大约好。

索引的使用

  • 最左前缀法则
    如果索引了多列(联合索引),要遵循最左前缀法则,最左前缀法则指查询从索引的最左列开始,并且不跳过索引的列。如果跳跃某列,索引将部分失效(后面的字段索引失效)。
  • 范围查询
    联合索引中,出现范围查询(>,<),范围查询右侧的索引失效
  • 索引列运算
    不要在索引列上进行运算操作,索引将失效。
  • 字符串不加引号
    字符串类型字段使用时,不加引号,索引将失效。
  • 模糊查询
    如果仅仅是尾部模糊匹配,索引将不会失效,如果是头部模糊匹配,索引失效。
  • or连接的条件
    用or分隔开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。
  • 数据分不影响
    如果MySQL评价使用索引比全表更慢,则不使用索引。
  • 覆盖索引
    尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select *。
    using index condition:查询使用了索引,但是需要回表查询数据;
    using where;using index:查询使用了索引,但是需要的数据都在索引列中能够找到,所以不需要回表查询数据。
    MySQL学习_第9张图片
  • 前缀索引
    当字段类型为字符串(varchar、text等),有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀建立索引,这样可以大大节约索引空间,从而提高索引效率。
    语法:
    create index idx_xxx on table_name(column(n));
    前缀长度
    可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表记录总数的比值,索引的选择性越高则查询效率越高。
  • 单列索引和联合索引
    单列索引:即一个索引只包含单个列。
    联合索引:即一个索引包含了多个列。
    在业务场景中,如果存在多个查询条件,考虑对于查询字段建立索引时,建议建立联合索引,而非单列索引。

索引的设计原则

  • 针对于大数据量且查询比较频繁的表建立索引;
  • 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引;
  • 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高;
  • 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引;
  • 尽量使用联合索引,减少单列索引,查询时联合索引很多时候可以覆盖索引,节约存储空间,避免回表,提高效率;
  • 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也越大,会影响增删改的效率;
  • 如果索引不能存储空值,请在创建表时使用not null约束它。当优化器知道每列是否包含null时,他可以更好地确定哪个索引最有效地用于查询。

SQL优化

插入优化

  • 批量插入
insert into table_name values(1, 'a'),(2, 'b'),(3, 'c');
  • 手动提交事务
start transaction;
insert into table_name values (1, 'a'),(2, 'b),(3,'c');
insert into table_name values (4, 'a'),(5, 'b),(6,'c');
commit;
  • 主键顺序插入
    将主键按照顺序插入。

  • 大批量插入数据
    如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。

主键优化

数据组织方式
在innoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表成为索引组织表(iot)

主键设计原则

  • 满足业务需求的情况下,尽量降低主键的长度;
  • 插入数据时,尽量按照顺序插入,选择使用AOTO_INCREMENT自增主键;
  • 尽量不要使用UUID做主键或者其他自然主键,如身份证号等;
  • 业务操作时,避免对主键的修改;

order by优化

Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后再排序缓冲区中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫filesort排序;
Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即是using index,不需要额外排序,操作效率高;

order by优化方法

  • 根据排序字段建立适合的索引,多字段排序时,也要遵循最左前缀原则;
  • 尽量使用覆盖索引
  • 多字段排序,一个升序,一个降序,此时需要注意联合索引在创建时的规则(asc/desc);
  • 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k) ;

limit优化

  • 减少深分页;
  • 创建索引,覆盖索引;

count优化

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count()的时候会直接返回这个数,效率高;
InnoDB引擎就麻烦了,它执行count(
)的时候,需要把数据一行一行的从引擎里面读出来,然后累计计数;

count的几种用法

todo未完待续


总结

        MySQL学习

Q&A

你可能感兴趣的:(tools,数据库,mysql,数据库,学习)