MySQL 进阶笔记

MySQL体系结构

  • 连接层

    最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的解决方案,服务器也会为安全接入的每个客户端验证它所具有的操作权限。

  • 服务层

    第二层架构主要完成大多数的核心服务功能,如 SQL 接口,并完成缓存的查询,SQL 的分析和优化,部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如过程、函数等。

  • 引擎层

    存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 和存储引擎进行通信。不同的存储引擎具有不同的功能,这样可以根据自己的需要,来选取合适的存储引擎。

  • 存储层

    主要是将数据存储在文件系统之上,并完成与存储引擎的交互。

存储引擎

简介

存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型。

  • 在创建表的时候,可以指定存储引擎:

    create table 表名(
    
    	...
    )engine=innodb;
    
  • 查看当前数据库支持的存储引擎:show engines;

引擎特点

InnoDB

  • 介绍InnoDB 是一种兼顾高性能的通用存储引擎,在 MySQL 5.5 之后,InnoDB 为默认存储引擎。

  • 特点

    • DML 操作遵循 ACID 模型,支持 事务

    • 行级锁,提高并发访问性能;

    • 支持 外键 foreign key 约束,保证数据的完成性和正确性。

  • 文件

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

    参数InnoDB_dile_per_table

  • 逻辑存储结构

    • 表空间—包含多个段

    • 段—包含多个区

    • 区(固定为 1M)—包含多个页

    • 页(固定为 16k)—包含多个行

MyISAM

  • 介绍MySQL 早期默认存储引擎

  • 特点

    • 不支持事务,不支持外键

    • 支持表锁,不支持行锁

    • 访问速度快

Memory

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

  • 特点

    • 内存存放

    • hash 索引(默认)

索引

概述

  • 概念 :索引是帮助 MySQL 高效获取数据的 数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

  • 作用 :用于提高查询时的效率,为字段指定相应的索引,数据库在查询的时候就会根据索引来进行数据的查询,优秀的索引可以使查询效率大大提高。

  • 优点

    • 提高数据检索的效率,降低数据库的 IO 成本。

    • 通过索引列对数据进行排序,降低数据排序的成本,降低 CPU 的消耗。

  • 缺点

    • 索引列也需要占用空间。

    • 索引大大提高了查询效率,同时也降低了更新表的速度,如对表进行insert update delete时,效率降低。

结构

  • B-Tree(多路平衡查找树)。

  • B+Tree :所有的数据都会出现在叶子节点;叶子节点形成一个单项链表。

  • hash :采用一定的 hash 算法,将键值换算成新的 hash 值,映射到相应的槽位上,然后存储在 hash 表中。

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

  • 相对于二叉树,层级更少,搜索效率高。

  • 对于 B-Tree ,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要保存大量数据,只能增加树的高度,导致性能降低。

  • 相对于 Hash 索引,B+Tree 支持范围匹配及排序操作。

分类

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

InnoDB 存储引擎中,根据索引的存储形式,可以分为:

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

操作语法

  • 创建索引create [unique|fulltext] index index_name on table_name(index_col_name,...);

  • 查看索引show index from table_name;

  • 删除索引drop index index_name on table_name;

性能分析

  • SQL各语句执行频率show [session|global] status like 'Com_______';

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

  • profile :执行一系列业务 SQL 的操作,然后通过如下指令查看指令的执行耗时:

    • 查看每一条 SQL 的耗时基本情况:show profiles;

    • 查看指定 query_idSQL 语句各个阶段的耗时情况:show profile for query query_id;

    • 查看指定 query_idSQL 语句 CPU 的使用情况:show profile cpu for query query_id;

  • explain执行计划

    • 作用 :用来查看每一条 sql 语句的执行优先顺序。

    • 语法 :直接在 select 语句之前加上关键字 explain/descexplain select 字段列表 from 表名 where 条件;

    • 字段含义:

      • idselect 查询的序列号,表示查询中执行 select 子句或者是操作表的顺序(id相同,执行顺序从上到下;id 不同,值越大,越先执行)。

      • select_type :表示 select 的类型,常见的取值有 simple(简单表,即不使用表连接或子查询)、primary(主查询,即外层的查询)、unionunion 中的第二个或者后面的查询语句)、subqueryselect/where 之后包含了子查询)等。

      • type :表示连接类型,性能由好到差的连接类型为 NULL、system、const、eq_ref、ref、range、index、all

      • possible_key :显示可能应用再这张表上的索引,一个或多个。

      • key :实际使用的索引,如果为 NULL,则没有使用索引。

      • key_len :表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。

      • rowsMySQL 认为必须要执行查询的行数,在 InnoDB 引擎的表中,是一个估计值,可能被并不总是准确的。

      • filtered :表示返回结果的行数占需读取行数的百分比,filtered 的值越大越好。

索引使用

  • 最左前缀法则 :如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的咧。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。

  • 范围查询 :联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。

  • 索引失效情况

    • 索引列运算:不要再索引列上进行运算操作,索引将失效。

    • 字符串不加引号:字符串类型字段使用时,不加引号,索引将失效。

    • 模糊查询:如果仅仅时尾部模糊匹配,索引不会失效,如果是头部模糊匹配,索引失效。

    • or连接的条件:用 or 分隔开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

    • 数据分布影响:如果 MySQL 评估使用索引比全表更慢,则不适用索引。

  • SQL提示:优化数据库的一个重要手段,简单来说,就是在 SQL 语句中加入一些认为的提示来达到优化操作的目的。

    • 使用时机为 from 表名 之后。

    • use index:使用该索引。

    • ignore index:不使用该索引。

    • force index:强制使用该索引。

  • 覆盖索引 :尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少 select *。在查询的时候,选择不同的索引,会有不同的结果,应尽量查询所需的字段,而非全部的数据,因为假如是辅助索引查询就会需要回表查询,为了使查询效率提高,尽量使用覆盖索引,即在辅助索引阶段就可以直接返回所需要的列。只需要将所需的字段进行查询,例如,我们可以直接返回叶子节点所挂的值,而不需要回表查询返回整个列的数据,只查询想要的数据,减少使用通配符 * 的频率。

  • 前缀索引 :当字段类型为字符串(varchar,text 等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。

    • 语法create index idx_XXXX on table_name(column(n));,其中n代表字段 colum 的前 n 个字符。

    • 前缀长度 :依据索引的选择性来定,选择性是指不重复的索引值和数据表的记录总数的比值通过两个语句来查看选择性大小,1是最好的。

      • select count(distinct 字段名)/count(*) from 表名;distinct用于去重。

      • select count(distinct substring(字段名,起始位置,截取长度))/count(*) from 表名;

  • 单列索引与联合索引

    • 单列索引:一个索引只包含单个列。

    • 联合索引:一个索引包含了多个列。

posted @ 2025-12-31 14:16  Amireux77  阅读(0)  评论(0)    收藏  举报