MySQL基础-存储引擎/索引/SQL优化

前言:本文均是基础内容,已掌握的建议跳过,你有更重要的内容需要学习。
MySQL-存储引擎
MySQL-索引
MySQL-SQL优化
相较于以前的文章有什么不同呢,算是复习。

SQL优化的尽头是索引!!!
索引的尽头是存储引擎!!!

零、本文纲要

一、存储引擎

  1. InnoDB
  2. MyISAM
  3. Memory

二、索引

  1. 索引相关问题
  2. SQL性能分析
  3. 索引使用
  4. SQL提示
  5. 覆盖索引
  6. 前缀索引
  7. 单列索引/联合索引选择

三、SQL优化

  1. 插入数据(大批量数据插入)
  2. 主键优化
  3. order by优化
  4. group by优化
  5. limit优化
  6. count优化
  7. update优化

一、存储引擎

-- 查看当前数据库支持的存储引擎
show engines;

1. InnoDB

  • ① 特点

支持事务 / 行级锁 / 支持外键

  • ② 文件

xxx.ibd
存储该表的表结构(frm-早期的 、sdi-新版的)、数据和索引

innoDB引擎的每张表都会对应这样一个表空间文件
查看对应表空间文件参数:show variables like 'innodb_file_per_table';

查看表空间文件的指令
ibd2sdi xxx.ibd

  • ③ 逻辑存储结构

表空间 / 段 / 区(64页) / 页(16KB) / 行

页是 InnoDB 存储引擎磁盘管理的最小单元,为了保证页的连续性,InnoDB 存储引擎每次从磁盘申请 4-5 个区。

2. MyISAM

  • ① 特点

不支持事务 / 表级锁 / 不支持外键

  • ② 文件

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

可以看到,不同于 InnoDB 存储引擎, MyISAM 存储引擎使用三个文件分别存储了表的内容。

3. Memory

  • ① 特点

内存存放 / hash索引(默认)

  • ② 文件

xxx.sdi:存储表结构信息

二、索引

1. 索引相关问题

思考题①: 为什么InnoDB存储引擎选择使用B+tree索引结构?

思考题②: select * from tb_user where name = 'Jobs' ;的查询过程?

回表查询:
a、走name字段的二级索引查找到对应的主键;
b、走聚集索引拿到对应主键的row数据。

思考题③:存储2000W条数据,InnoDB主键索引的B+tree高度为多高呢?
假设:1行数据1KB,一页可以存储16行数据。InnoDB的指针大小为6字节,假设主键为Bigint8字节。

8 * n + 6 * (n + 1) = 16 * 1024 → n = 1069;
假设两层索引,(1169 + 1) * (1169 + 1) * 16 = 21902400;
B+tree的高度仅需3层,既可以存放2000W条数据。

思考题④:用户表含(id,username,password,status)四个字段,大数据量的情况下如何建立索引,优化SQL执行效率?
SQL: select id, username, password from tb_user where username = 'Jobs';

2. SQL性能分析

  • ① 查询SQL频率

SHOW [SESSION|GLOBAL] STATUS

-- session 是查看当前会话 ;
-- global 是查询全局数据 ;
SHOW GLOBAL STATUS LIKE 'Com_______';

  • ② 慢查询日志

SHOW VARIABLES LIKE 'slow_query_log';

> vim /etc/my.cnf
> # 插入下方数据
> # 1表示开启,0表示关闭
> slow_query_log=1
> # 慢查询的设定时间10s,可以根据实际需求调整
> long_query_time=10

慢查询日志位置:/var/lib/mysql/localhost-slow.log

  • ③ profile详情

SELECT @@have_profiling ;
SET profiling = 1;

-- 查看每一条SQL的耗时基本情况
SHOW PROFILES;
-- 查看指定query_id的SQL语句各个阶段的耗时情况
SHOW PROFILE FOR QUERY query_id;
-- 查看指定query_id的SQL语句CPU的使用情况
SHOW PROFILE CPU FOR QUERY query_id;

  • ④ explain

-- 直接在select语句之前加上关键字 explain / desc
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件 ;

字段 含义
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 的值越大越好。

a、type

一般通过主键或者唯一索引查询,type类型会是const;
一般通过非唯一索引查询,type类型会是ref(注意:联合索引部分失效也是ref);
一般对索引进行遍历的查询,type类型会是range/index;

3. 索引使用

① 联合索引-最左前缀法则,联合索引查询跳跃某一索引列,索引将会部分失效
② 联合索引-范围查询(>,<)右侧的列索引失效
注意:
a、范围查询该列的索引还是生效的;
b、范围查询的情形下使用(>=,<=),则右侧索引也能生效;

③ 索引列-函数运算,索引失效
④ 索引列-隐式类型转换,字符串类型不加单引号'',索引失效
⑤ 索引列-模糊查询,左侧使用'%'如'%查询字段',索引失效

⑥ or连接条件-一侧有索引、一侧无索引,索引失效
⑦ 数据分布影响-如果全表扫描更快,则不使用索引
比如:IS NULL / IS NOT NULL-如果全表扫描更快,则不使用索引

4. SQL提示

USE INDEX-建议使用指定索引
EXPLAIN SELECT * FROM tb_user USE INDEX(idx_user_pro) WHERE profession = '软件工程';

FORCE INDEX-强制使用指定索引
EXPLAIN SELECT * FROM tb_user FORCE INDEX(idx_user_pro) WHERE profession = '软件工程';

IGNORE INDEX-忽略使用指定索引
EXPLAIN SELECT * FROM tb_user IGNORE INDEX(idx_user_pro) WHERE profession = '软件工程';

5. 覆盖索引

覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。

当EXPLAIN某些查询的type类型一致(const、ref),可以通过查看Extra额外信息来判断查询效率。

Extra 含义
Using where; Using Index 查找使用了索引,但是需要的数据都在索引列中能找到,
所以不需要回表查询数据
Using index condition 查找使用了索引,但是需要回表查询数据

6. 前缀索引

节约索引空间,减少磁盘IO压力,从而提高索引效率。

创建前缀索引的语法
CREATE INDEX idx_xxxx ON table_name(column_name(len)) ;

索引的选择性
SELECT COUNT(DISTINCT column_name) / COUNT() FROM table_name ;
SELECT COUNT(DISTINCT substring(column_name, offset, len)) / COUNT(
) FROM table_name ;

7. 单列索引/联合索引选择

在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,而非单列索引。

三、SQL优化

1. 插入数据(大批量数据插入)

test.txt文件数据为
1,39890001,Jobs,2022-01-01,tech
2,39890002,Tom,2022-01-03,tech
...

Load指令,大批量数据插入
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
FIELDS TERMINATED BY ',' LINES STARTING BY '\n';

LOAD指令官方文档

2. 主键优化

回顾:
InnoDB逻辑存储结 构表空间 / 段 / 区(64页) / 页(16KB) / 行
索引组织表:index organized table,跟据主键顺序组织存放

页面存储 / 页面合并 / 页面分裂
页面合并阈值设置官方文档
顺序插入可以减少频繁的合并分裂操作(merge-split behavior),进而提升SQL效率。

3. order by优化

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

创建升&降序索引(满足最左前缀法则)
CREATE INDEX idx_one_two ON table_name(index_one ASC ,index_two DESC);
查看默认磁盘缓冲区大小(默认256KB)
SHOW VARIABLES LIKE 'sort_buffer_size';

4. group by优化

索引的使用也是满足最左前缀法则的

5. limit优化

一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。

覆盖索引 + 子查询优化
EXPLAIN SELECT * FROM table_name t1 ,
(SELECT index_name FROM table_name ORDER BY index_name LIMIT page,page_size) t2

WHERE t1.index_name = t2.index_name;

6. count优化

按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(),所以尽量使用 count()。

7. update优化

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁升级为表锁 。

四、结尾

以上即为MySQL基础-存储引擎/索引/SQL优化的全部内容,感谢阅读。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容