业务数据LEFT JOIN 多表查询慢--优化操作
首先你会想到,给表加索引,那么mysql会给主键自动建立索引吗?
会的,当然会。
在我们查询的业务表操作的时候,表业务数据庞大起来的时候,以及left join多的时候,甚至多表关联到几十张表的时候,查询是慢到外婆家里去了。
这时候,只需要给表join查询的字段,及表结构,进行索引优化,即可解决这个慢的问题。
一,首先利用explain 关键字对查询的SQL进行分析。
![](https://img2020.cnblogs.com/blog/1563479/202112/1563479-20211217150447501-338161548.png)
![](https://app.yinxiang.com/shard/s31/res/2a0588a4-0159-40c5-b59c-6baaca6357bf/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211217144812.png)
# type=ALL,全表扫描,MySQL遍历全表来找到匹配行
# type=index,索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表
# type=range,索引范围扫描,常用于<、<=、>、>=、between等操作
# type=ref,使用非唯一索引或唯一索引的前缀扫描,返回匹配某个单独值的记录行
# type=eq_ref,类似ref,区别在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配
# type=const/system,单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理
# type=NULL,MySQL不用访问表或者索引,直接就能够得到结果
![](https://img2020.cnblogs.com/blog/1563479/202112/1563479-20211217150508985-1779592053.png)
![](https://app.yinxiang.com/shard/s31/res/fde08ade-8c49-4d7f-b8df-69eb940984f4/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211217144919.png)
*** 重点来了,为表添加索引,如果发现分析出来的表type 为all ,我们首先想到这个表没加索引,我们给他加上 ***
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
mysql引擎放弃使用索引而进行全表扫描的几种情况:
- 应尽量避免在 where 子句中对字段进行 null 值判断,可以设置默认值0
- 应尽量避免在 where 子句中使用!=或<>操作符
- 应尽量避免在 where 子句中使用or 来连接条件,in 和 not in 也要慎用
-
模糊查询select id from t where name like ‘%李%’也会全表扫描,若要提高效率,可以考虑全文检索
![](https://app.yinxiang.com/shard/s31/res/a7d049f4-e788-4d05-8fa0-fbc4abaf90c6/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211217145508.png)
------------------添加完后--大功告成----------------------
MySQL目前主要有以下几种索引类型:
1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引
1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引
mysql Hash索引和BTree索引区别
一、BTreeBTree索引是最常用的mysql数据库索引算法,因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量,例如:
select * from user where name like ‘jack%’;
select * from user where name like ‘jac%k%’;
如果一通配符开头,或者没有使用常量,则不会使用索引,例如:
select * from user where name like ‘%jack’;
select * from user where name like simply_name;
一、Hash
1. hash索引查找数据基本上能一次定位数据,当然有大量碰撞的话性能也会下降。而btree索引就得在节点上挨着查找了,很明显在数据精确查找方面hash索引的效率是要高于btree的;
2. 那么不精确查找呢,也很明显,因为hash算法是基于等值计算的,所以对于“like”等范围查找hash索引无效,不支持;
3. 对于btree支持的联合索引的最优前缀,hash也是无法支持的,联合索引中的字段要么全用要么全不用。提起最优前缀居然都泛起迷糊了,看来有时候放空得太厉害;
4. hash不支持索引排序,索引值和计算出来的hash值大小并不一定一致。
2. 那么不精确查找呢,也很明显,因为hash算法是基于等值计算的,所以对于“like”等范围查找hash索引无效,不支持;
3. 对于btree支持的联合索引的最优前缀,hash也是无法支持的,联合索引中的字段要么全用要么全不用。提起最优前缀居然都泛起迷糊了,看来有时候放空得太厉害;
4. hash不支持索引排序,索引值和计算出来的hash值大小并不一定一致。
MySQL是只支持一种JOIN算法Nested-Loop Join(嵌套循环链接) ---
没有索引时会走,Block Nested-Loop Join比Simple Nested-Loop Join多了一个中间join buffer缓冲处理的过程
没有索引时会走,Block Nested-Loop Join比Simple Nested-Loop Join多了一个中间join buffer缓冲处理的过程
没有索引时:
![](https://img2020.cnblogs.com/blog/1563479/202112/1563479-20211217150538748-53685627.png)
![](https://app.yinxiang.com/shard/s31/res/01bce33a-6243-4fd1-af14-3ea59aa214c5/726254-20201119153237051-1530370807.png)
当关联字段有索引时,走的是Index Nested-Loop Join(索引嵌套链接) ---
有索引时;
![](https://img2020.cnblogs.com/blog/1563479/202112/1563479-20211217150551379-608109817.png)
![](https://app.yinxiang.com/shard/s31/res/410d5e84-d37f-4053-84a3-036efe7359f7/726254-20201119153253722-365652518.png)