开发者学堂课程【MySQL 高级应用 - 索引和锁:小表驱动大表】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/598/detail/8623
小表驱动大表
目录:
一、查询优化
二、优化原则
三、优化思路
一、查询优化
1.分析
(1)观察,至少跑1天,看看生产的慢 SQL 情况。
(2)开启慢查询日志,设置阙值,比如超过5秒钟的就是慢 SQL,并将它抓取出来。
(3)explain+慢 SQL 分析
Explain 能够告诉你这个查询在数据库中是一个什么样的执行计划来实现的。
首先我们需要有个目标,通过不断调整尝试,再借助 Explain 来验证结果是否满足自己的需求,直到得到预期的结果。
(4)show profile 分析
MySQL 的 Explain 执行计划可以用来对Sql语句进行分析,是否进行全表扫描,是否用了索引,或者是 sql 语句先后执行计划,有没有用临时表等等,由此来进行 Sql 优化,
而 show Profile 和 Explain 一样都是用来查看 Sql 语句分析的,但是形式不一样, show Profile 用来分析当前会话语句执行的资源消耗情况,能清晰的知道 sql 执行过程,以及过程中消耗的时间。
(5)运维经理 or DBA ,进行 SQL 数据库服务器的参数调优。
2.总结
(1)慢查询的开启并捕获
(2)explain+慢 SQL 分析
(3)showprofile 查询 SQL 在Mysq1 服务器里面的执行细节和生命周期情况
(4)SQL 数据库服务器的参数调优。
永远小表驱动大表 Case:
for(int i =5;...)
for(int j=1000)
{
}
}
for(int i =1000;...)
{
for(int j=5){
MySQL 中的 Join,只有 Nested Loop 一种 Join 方式,也就是 MySQL 的 Join 都是通过嵌套循环来实现的。
驱动结果集越大,所需要循环的次数就越多,那么被驱动表的访问次数自然也就越多,而每次访问被驱动表,即使需要的逻辑 IO 很少,循环次数多了,总量自然也不可能很小,而且每次循环都不能避免的需要消耗 CPU,所以 CPU 运算量也会跟着增加。
使用小的部门表,得到小表,连接大表
二、优化原则
优化原则:小表驱动大表,即小的数据集驱动大的数据集。
RBO 基于规则
select * from A where id in (select id from B)
等价于:
for select id from B
for select * from A where A.id=B.id
当 B 表的数据售必须小于 A 表的数据集时,用 in 优于exists
select * from A where exists(select 1 fromB where B.id=A.id)
等价于
for select * from A
for select *fromBwhere B.id=A.id
当 A 表的数据集系小于 B 表的数据集时,用 exists 优于 in。
注意:
A 表与 B 表的 ID 字段应建立索引。
EXISTS
SELECT..FROM table WHERE EXISTS(subquery)
该语法可以理解为:
将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。
提示
1. EXISTS(subquerv) 只返回TRUE 或 FALSE,因此子查询中的 SELECT* 也可以是SELECT1 或 seleutX,官方说法是实际执行时会忽略 SELECT 清单,因此没有区别
2. EXISTS 子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比,如果担忧效率问题,可进行实际检验以确定是否有效率问题。
3.EXISTS 子查询往往也可以用条件表达式、其他子查询或者 JOIN 来替代,何种最优需要具体问题具体分析
三、查询优化思路
1、优化更需要优化的查询
2、定位优化对象的性能瓶颈
3、明确优化的目标
4、从 Explain 入手
5、多使用 profile
6、永远用小结果集驱动大结果集
7、尽可能在索引中完成排序
8、只取出自己需要的字段(Columns)
9、仅仅使用最有效的过滤条件
10、尽可能避免复杂的 join