mysql 调优方法论

mysql 调优方法论

什么情况下该用索引,什么情况不该用索引?

理论上应该使用索引的场景:

  1. where 条件后面字段;
  2. distinct 字段;
  3. group by 字段;
  4. order by 字段;
  5. join 连接字段;
  6. 具有唯一特征的字段;

不建议使用索引的场景:

  1. 字段选择度底的字段,比如性别;
  2. 表的记录特别少;
  3. 频繁更新的列;

索引失效场景:

  1. 隐士类型转换,比如字段定义为varchar,而传入的值为数字,未加引号;
  2. 不满足最左匹配原则;
  3. 模糊查询;
  4. 左边使用表达式,索引字段不独立;
  5. 经过mysql 优化器分析,使用过滤效率反而不及全表扫描;
  6. 使用or 连接的多个条件,部分没有索引,部分有索引
  7. not null 的说法:若字段定义的允许为null,则有个标记字段专门标注是否为null。 所以尽量设置字段不为null

Group By 语句调优

  1. 算法:
    a. 松散索引扫描:条件: 单张表,符合最左匹配原则,min和 max可用
    b. 紧凑索引扫描;
    c. 临时表(using temporary),需要优化

Order By 语句调优

算法: 常规排序(rowid排序)

	1. 从表中获取满足where条件的记录;
	2. 对于每条记录,将主键和排序字段放入sort buffer(由sort_buffer_size控制)
	3. sort buffer若 不能排序所有的主键和排序字段,则排序好先放入临时文件;sort  buffer排序用快排,文件合并用归并排序
	4. 获取排好序的(主键,排序字段),通过id去取select 需要返回的其他字段;
	5. 返回结果集;

全字段排序(优化排序)

		1. 从表中获取满足where条件的记录;
   		2. 对于每条记录,将主键和select字段全部放入sort buffer(由sort_buffer_size控制)
   		3. sort buffer若 不能排序所有的主键和排序字段,则排序好先放入临时文件;sort  buffer排序用快排,文件合并用归并排序
   		4. 返回结果集;
通过max_length_for _sort_data 可以控制是全字段排序还是rowid排序;

打包字段排序:

同全字段排序顺序,区别在于保存时候,将字段紧密地存储在一起而不是固定长度;

尽量防止二次排序(使用覆盖索引);
如果做不到,考虑是否放大排序缓存区大小,减少排序文件大小;

limit 语句调优

distinct 语句调优

  1. 算法: a. 松散索引扫描;b. 紧凑索引扫描;c. 临时文件

JOIN 语句调优

  1. 算法:
    a. Nested Loop Join (NLJ):
for(int a=0;a<a';a++){
	for(int b=0;b<b';b++){
		for(int c=0;c<c';c++){
			{匹配}
		}
	}
}

b. Block Nested Loop Join (BNLJ);

for(int a=0;a<a';a++){
	for(int b=0;b<b';b++){
		if(buffer 满了 ){
			for(int c=0;c<c';c++){
				{buffer里面和c匹配}
			}
		}else{
			添加到 buffer
		}	
	}
}

c. Batched key access Join(BKA);
匹配到的数据,先排序,再去主键索引树中去读取select字段数据;
特点:读取select字段数据过程,将随机IO 转换为了顺序IO(参考MRR 描述),但是增加了排序的开销;
d. Hash Join; (mysql 8.0.20之后才出现的,为了替换BNLJ。将缓存放到hash,加快速度)

count 语句调优

  1. 如果不加条件,myisam 和 innodb 8.0.13 之后的,都能很快获取到;
  2. 如果自己确实想要快,对准确性要求高,可以自己维护一个统计表;
  3. 如果堆准确性要求比较低,可以用schame里面的,或者explain里面的都可以;
  4. count(*) 和 count(1) 在效率上基本一致;count(字段)会不统计字段为null的行,需要关注;
  5. 若没有非主键索引,使用主键索引count; 若有非主键索引,使用非主键索引;若有多个非主键索引,使用索引长度短的count。(原因嘛,就考虑到页存储问题,尽量一页存储的多,那读的页相对毕竟少)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340