https://www.bilibili.com/video/BV1iq4y1u7vj?p=141
数据库调优的几个维度:
关于数据库调优的知识是非常分散的。 不同的DBMs,不同的公司,不同的职位,不同的项目遇到的问题都是不一样的。 这里我们分为三个章节进行细致讲解。
虽然SQL查询优化技术有很多,但在大方向上可以分为物理查询优化
和逻辑查询优化
两大类:
物理查询优化
是通过索引
与表的连接
等技术进行优化,关键是掌握索引的使用。逻辑查询优化
说白了就是换一种执行效率更高的sql写法另一个讲解:
满足最左原则的查询:
全值匹配我最爱: 联合索引的字段全部用到了,且是从左往右按顺序的;完全是为这条SQL量身定做的索引
(2) 二哥没了
二哥没了,可以看出来 按照(1,3)进行检索和按照(1)进行检索,对索引的使用效率是一样的;key_len都是74,引用也只有一个;说明找大哥的时候用到了索引,但是找三弟的时候没用到索引;
最佳左前缀法则: 如果索引用了多列,检索条件从索引的最左列开始并且不跳过中间的列 (1.火车头不能丢 2.中间不能断)
图中可以看出,一个索引的key_len是74,两个是78,三个是140,在最后一个sql中,age用了范围,key_len是78,只有name和age用到了索引,pos的索引失效,ref为null
https://www.bilibili.com/video/BV1iq4y1u7vj?p=143
左连接,左表为驱动表,原理为:
for(记录1 in 左表){ for(记录2 in 右表){ 记录1 join 记录2 } } 所以时间复杂度O(n*m); 由于被驱动表需要被遍历n次,所以查询优化器进行了优化, 使用`join buffer` 将被驱动表缓存起来,从而提升检索速度;
(2) join字段 被驱动表上建立索引
在左外连接的场景下,由于驱动表所有数据都要,因此可以接受左表全表扫描,可以在被驱动表的连接字段上建立索引;
外连接总结:
(3) 都上加索引
结论1: 对于内连接来说,两个表的地位是一样的,查询优化器可以决定谁作为驱动表,谁作为被驱动表;所以不是随机的;
此时,向type表添加数据,使得type表数据量更大:
结论2: 内连接中,都建立了索引时,数据量更大的表会被优化为被驱动表
内连接总结:
https://www.bilibili.com/video/BV1iq4y1u7vj?p=144&spm_id_from=pageDriver
补充说明:
Simple Nested-Loop Join
中,驱动表A有多少条记录,就加载多少次B表;现在优化为一次用N条 驱动表记录来join B表;这样就减少了B表加载次数;Join Buffer
小 指的是 :表行数 * 每行大小
更小,buffer 可以存更多,减少被驱动表IO;
Mysql5.7 中使用的就是Block Join
https://www.bilibili.com/video/BV1iq4y1u7vj?p=145&spm_id_from=pageDriver
案例
加上limit后,不需要全表回表查询,只需要topN条进行回表,因此此时使用上了索引;
双路排序:要进行两次磁盘扫描获取结果;
第一次扫描:读取行指针
和order by的列
; 然后将order by列进行排序
第二次扫描:由于行指针
和order by的列
已经排好序了,然后第二次扫描磁盘,通过行指针
读取其他所需要的字段;
单路排序:只扫描一次磁盘
空间换时间
https://www.bilibili.com/video/BV1iq4y1u7vj?p=146&spm_id_from=pageDriver
https://www.bilibili.com/video/BV1iq4y1u7vj?p=147&spm_id_from=pageDriver
Using Index Condition
表示使用到了索引下推使用ICP前的扫描过程
先通过索引idx_key1,过滤到100多条数据;然后回表100多次,在聚簇索引的叶子节点中的数据 根据 like '%a’的条件找到目标数据;
ICP后
通过非聚簇索引idx_key1,就能找到满足 key1>‘z’ 的索引;
后面一个条件 恰好用的也是字段 key1,那么我们直接可以在非聚簇索引上进行二次过滤,而不需要回表查询了;
- 当前查询只有zipcode='00001’这个条件用到了索引;
- 由于lastName也属于非聚簇索引的一部分,因此用到了ICP,所以Extra中有Using index condition;
- 由于where条件中还有个address是非索引字段,所以Extra中有Using where
ICP的本质就是使用二级索引,然后减少回表次数;所以只有在用二级索引的时候才会产生ICP
https://www.bilibili.com/video/BV1iq4y1u7vj?p=149&spm_id_from=pageDriver
统计表记录数:
(1)count(*) 和 count(1) 没差;选择空间小(key_len小)的二级索引进行计算;
(2)InnoDB时间复杂度O(n) MyIsam是O(1)
(3)count(具体字段):尽量选择key小的二级索引;因为统计会加载数据到内存,所以选择空间小的
https://www.bilibili.com/video/BV1iq4y1u7vj?p=150&spm_id_from=pageDriver