SQL执行频率
show [session|global] status like ‘com__(七个下划线)_’;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次
通过这个指令我们可以查看当前数据库是以查询为主还是更新为主。如果是以查询为主,那么就要考虑对数据库的索引进行优化了。
慢查询日志。定位需要对哪些查询语句进行优化。
MySQL的配置文件(/etc/my.cnf)中配置如下信息
# 开启MySQL慢日志查询开关
slow_query_log=1
# 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
日志信息所在:/var/lib/mysql/localhost-slow.log
这样在慢查询日志中就会记录那些查询效率较低的sql语句
profile :这个可以让我们知道sql语句运行时的时间都消耗在哪里了,用的不是很多
explain:获取sql的执行计划
使用方式:直接在sql语句前面加explain,或者加desc,作用基本一致,使用expalin多一些
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件 ;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-59U9tmMo-1664243430019)(/Users/wangkx/Desktop/wkx的md笔记/img/image-20220926195406219.png)]
各个字段的含义:
对于insert
批量插入:一般是500-1000条
手动提交事务:执行一系列insert之前开启事务,执行完提交事务,避免事务的频繁开启和提交
按照主键顺序插入
对于一次有几百万条数据
这个时候使用insert效率会很低,可以使用load指令把本地文件大批量加载到数据库中
-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-local-infile -u root -p
-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
-- 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n' ; //每个字段按照逗号隔开,行间按照换行隔开
在InnoDB引擎中,数据行是记录在逻辑结构 page 页中的,每一个页的大小是固定的,默认16K,所以说一个页中所存储的行也是有限的。然后因为使用的是B+索引,表数据是按照主键顺序存储的,页与页之间的顺序是有序的。
mysql规定每个页至少包含两个数据(只有一个数据就是链表了)。
当主键顺序插入时,第一个页满了就往第二个页写,页与页之间使用指针相连。
但是当主键乱序插入时,新数据不会直接插入到空白页(这样做数据会无序),而是会把对应页的后半部分数据移动到空白页,然后再把要插入的值插入到空白页。最后还得重新设置链表的指针。效率就很低了
删除数据时,把对应位置标记为无效,当页中删除的记录达到 一个阈值的时候(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
首先MySQL的排序有两种方式
原则:
在分组操作时,给group by后的条件加索引,尽量加联合索引
分组操作时,索引的使用也是满足最左前缀法则的
在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低,因为会先对前面的记录排序
优化思路: 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化
举例:我们可以先使用limit只查出id(用到覆盖索引),然后把这张结果表和原表做一次连表查询
select * from tb_sku t ,
(select id from tb_sku order by id limit 2000000,10) a
where t.id = a.id;
不是很容易优化,非要优化的话可以使用redis自己计数。
按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(),所以尽量使用 count()。
在InnoDB引擎中,执行一条update语句:update course set name = ‘SpringBoot’ where name = ‘PHP’
如果我们给name字段加了索引,此时InnoDB加的是行锁,其他事务可以操作别的记录,并发性能高
但是如果name字段没有索引,或者name字段索引失效,update时直接升级为表锁,其他事务无法操作数据库表。
所以要尽量使用索引字段为条件来更新数据,增加并发性。