全面解析MySQL底层概念

mysql的概念

(1) mysql的架构

客户端请求--->连接器(验证用户身份,给予权限)--->查询缓存(存在则直接返回,不存在则执行后续操作 --->分析器(对SQL进行词法分析和语法分析操作) --->优化器(主要对执行的sql优化选择最优的执行方案方法)--->执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)--->去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)

(2) mysql有哪些引擎

mysql支持的存储引擎有八种,我们常用的两种InnoDB和MyISAM。这两者的区别:

1.InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

2.InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;

3.InnoDB 是聚簇索引,MyISAM 是非聚簇索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先通过辅助索引查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

4.InnoDB 不保存表的具体行数,执行select count(*) from table 时需要全表扫描。而 MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

5.InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

(3) mysql的索引 index

索引(Index)是帮助MySQL高效获取数据的,索引的本质是:有序的数据结构

索引的优缺点:

(1)索引的优点:

减少查询需要检索的行数,加快查询速度,避免进行全表扫描,这也是创建索引的最主要的原因。如果索引的数据结构是B+树,在使用分组和排序时,可以显著减少查询中分组和排序的时间。通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

(2)索引的缺点:

当对表中的数据进行增加、删除和修改时,索引也要进行更新,维护的耗时随着数据量的增加而增加。索引需要占用物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

索引常用命令:

|---------------------------------------------------------------------------------------------------------------|
| 创建索引: CREATE [UNIQUE] INDEX indexName ON mytable(username(length)); |
| 实例: CREATE INDEX name_index ON tb_teacher(t_name(20)); ALTER table tb_teacher ADD INDEX phone_index(t_phone); |
| 删除索引: DROP INDEX [indexName] ON mytable; |
| 查看表中的索引 SHOW INDEX FROM tb_teacher; |

索引的类型:

普通索引:仅加速查询

唯一索引:加速查询 + 列值唯一(可以有null)

主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并 减少回表查询 遵循最左匹配原则

维护成本较高

(4) 如何判断索引是否生效?

在查询语句前加上explain,查看sql语句的执行计划。type:这是重要的列,显示连接使用了何种类型。它在 SQL优化中是一个非常重要的指标。如果type的类型是ALL的话代表语句没有走索引,走了全表扫描。

(5)为什么 Mysql用B+树做索引而不用B-树

因为B+树的data只存储在叶子节点上,B树的所有节点都存储了key和data,B+树的非叶节点不存储data,这样一个节点就可以存储更多的索引值,可以使得树更矮(高度更小),减少I/O次数,磁盘读写代价更低,I/O读写次数是影响索引检索效率的最大因素;

B+树的所有叶结点构成一个有序链表,顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

(6) 索引失效 ?

(1)使用组合索引没有满足最左匹配原则,也就是最左边的字段一定要在查询条件中。

(2)where 后面有不是索引的字段,但是查询的结果集,超过了总行数 25%,优化器就会认为没有必要走索引了。

(3)加了索引的字段在查询条件中参与运算或者使用了函数

(4)字段的类型不同

mysql发现如果是int类型字段作为查询条件时,它会自动将该字段的传参进行隐式转换, 把字符串转换成int类型。

(5)模糊查询%放前边会造成索引失效

(6)列对比也会造成索引失效

(7)查询条件用or时,如果or的字段中有没有索引的字段那么索引就会失效

解决办法把两个条件分开查询,在使用UNION 进行连接,这样有索引的字段就会走索引。

(7) sql优化

1、查询SQL尽量不要使用select *,而是select具体字段。

理由:只取需要的字段,节省资源、减少网络开销。

select * 进行查询时,很可能就不会使用到覆盖索引了,就会造成回表查询。

2、如果知道查询结果只有一条或者只要最大/最小一条记录,建议用limit 1

加上limit 1后,只要找到了对应的一条记录,就不会继续向下扫描了,效率将会大大提高。

  1. 应尽量避免在where子句中使用or来连接条件,如果or的字段中有没有索引的字段那么索引就会失效。解决办法把两个条件分开查询,在使用UNION 进行连接,这样有索引的字段就会走索引。
  2. 优化你的like语句

日常开发中,如果用到模糊关键字查询,很容易想到like,但是like很可能让你的索引失效。把%放前面,并不走索引。

5.尽量避免在索引列上使用mysql的内置函数,查询的字段不能使用内置函数否则索引失效

6.应尽量避免在where子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫描.

7、Inner join 、left join、right join,优先使用Inner join,如果是left join,左边表结果尽量小表

8、应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

9、使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则

10.对查询进行优化,应考虑在where及order by涉及的列上建立索引,尽量避免全表扫描。

(8) SQL执行顺序

from on join where group by(开始使用select中的别名,后面的语句中都可以使用) avg,sum.... having select distinct

order by limit

相关推荐
JhonKI10 分钟前
【MySQL】表的基本查询(下)
数据库·mysql·oracle
微风轻吟挽歌14 分钟前
Mysql唯一约束
数据库·mysql
AR_xsy15 分钟前
MySQL不能被其他地址访问,授权问题解决(8.x,,5.x)
数据库·mysql
niech_cn23 分钟前
Ai编程从零开始全栈开发一个后台管理系统之接口开发node+express+mysql(十五)
mysql·express·ai编程
m0_748256561 小时前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
落寞书生1 小时前
docker安装mysql 实现主从同步
运维·mysql·docker·主从同步·docker 安装mysql
骷大人3 小时前
mysql开启配置binlog
数据库·mysql
Yolo_nn3 小时前
MySQL_第14章_存储过程与函数
数据库·mysql·存储过程·函数
Coder_Cui4 小时前
解决MySQL Workbench 8.0点击Server Status按钮报错问题
mysql