数据库架构
1索引模块
1.1为什么使用索引?
全表扫描会查询整个表所有的数据块、数据页,速度太慢,
使用索引能避免全表扫描,加快速度
1.2什么信息建立索引?
主键、唯一键等让数据产生区分性的都可以建立索引
1.3索引的数据结构
B+Tree、Hash结构(Mysql不显式支持)、BitMap(Mysql不支持)
B-Tree
定义
- 根结点至少包含2个节点
- 2<=树中每个节点孩子数<=m
- 除根结点、叶子节点,至少有ceil(m/2)个孩子
- 所有叶子节点均在同一层
- 假设每个非终端节点,关键字个数为n,K代表当前层关键字,P代表孩子指针
a. Ki(i=1…n)为关键字,K(n-1)<K(n)
b. ceil(m/2)-1 <= n <= m-1
c. P[1]、P[2]…P[M], P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其他P[i]指向关键字属于(K[i-1],K[i])的子树
图例:
B+Tree
定义
- 非叶子节点的子树与关键字个数相同
- 非叶子节点的子树指针P[i],指向关键字值(K[i],K[i+1])的子树
- 非叶子节点仅用来索引,数据在叶子上
- 所有叶子节点均有一个链指针指向下一个叶子节点
图例:
1.4索引衍生问题
a.如何定位并优化慢查询SQL
我们拟造一个场景,模拟一个慢查询排查的过程。注:此场景仅为一个参考,提供一个优化查询速度的思路,具体情况还需结合场景调整
- 根据慢日志查找慢查询
首先,我们执行下面查询语句
# 开启慢查询日志,设置慢查询界限为1s
set global slow_query_log = on;
set global long_query_time = 1;
# 执行查看释放开启慢查询日志
show variables like '%query%';
如图,我们发现慢查询日志虽然开启,但是long_query_time仍然为默认的10s,我们此时需要重新连接一次数据库
set global ***的方式重启后失效,永久设置请修改my.ini(mac修改/etc/my.cnf)
提前准备一个表,插入20W条数据,执行查询
执行下面语句查询慢查询sql条数
show status like '%slow_queries%';
执行结果(我执行了4次)
cat 查看刚才的慢日志文件
2. 使用Explain语句
针对查询优化,我们重点看type、extra这两列
type
出现index、all就需要优化了
速度优先级system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all
extra
出现以下两种情况,性能大大受到影响
extra | 说明 |
---|---|
Using filesort | 表示MySQL会对查询结果使用外部索引排序,不是通过表内部按索引次序读到相关内容,而是放在内存或磁盘排序,称为‘文件排序’ |
Using temporary | 表示对查询结果排序使用临时表,通常出现于group by 和order by |
- 修改查询语句 | 增加索引
增加索引
再次执行查询
美滋滋,好歹是在毫秒级别了,执行分析看到走索引了
b.联合索引的最左匹配原则的成因
c.索引越多越好?
当然不是!
- 数据量小的表不需要建立索引,建立索引需要额外增加索引开销
- 数据变更需要维护索引,因此更多的索引意味着更多的维持成本
- 索引与空间成正比
转载:https://blog.csdn.net/Mrkaizi/article/details/106178717
查看评论