全面解析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

相关推荐
zhangjin122231 分钟前
kettle从入门到精通 第九十四课 ETL之kettle MySQL Bulk Loader大批量高性能数据写入
大数据·数据仓库·mysql·etl·kettle实战·kettlel批量插入·kettle mysql
深圳厨神40 分钟前
mysql对表,数据,索引的操作sql
数据库·sql·mysql
hweiyu0043 分钟前
从JVM到分布式锁:高并发架构设计的六把密钥
jvm·redis·分布式·mysql·etcd
小陈又菜1 小时前
MySQL-触发器
数据库·mysql·database·触发器
平凡的小y1 小时前
MySQL内置函数
数据库·mysql
慕丹1 小时前
虫洞数观系列三 | 数据分析全链路实践:Pandas清洗统计 + Navicat可视化呈现
python·mysql·数据挖掘·数据分析·pandas
luluoluoa1 小时前
SQL、mySQL与SQLite简单理解
sql·mysql·sqlite
逊嘘1 小时前
【MySQL】表的增删改查(拓展)
java·数据库·mysql
猫咪-95272 小时前
Mysql之事务(上)
数据库·mysql
GOTXX2 小时前
BoostSiteSeeker项目实战
前端·c++·后端·mysql·搜索引擎·项目实战·boost