系统优化专题

189 阅读8分钟

mysql的结构:

mysql的结构分为

客户端,也就是如jdbc 服务端:服务管理(连接池,sql存储,sql解析,sql优化,sql缓存),存储引擎(数据存储的结构),文件层(存储数据文件,日志),同时mysql的存储引擎时可插拔式的

存储引擎:(主要关注的时事务,锁,索引)

innodb(支持行级锁,事务,外键)

默认事务隔离级别时可重复读

外键:

frm存储的时表结构,ibd存储的是数据和索引

myisam不支持事务,查询的速度更快

大部分场景都是使用innodb

如果对数据的完整性要求不高,对查询要求高,可以选择myisam

menery不推荐使用,他是存储在内存,虽然访问快,但是断电后,就数据丢失,

覆盖索引,查询的数据,已经是包含在索引中,这样就不会存在回表的现象;

extra(索引的使用情况)

索引的选择

尽量使用符合索引,因为数据库在执行的时候,只会选择多个索引中的一个,而复合索引,可能会更精确查询

1、大批量插入数据的优化:(按主键顺序插入)

2、插入前,关闭唯一性校验,导入后,再设置回

3、手动提交数据

如果数据量大,分页提交

排序后,插入

使用关联查询替代子查询

myisam的内存优化

内存管理的优化(调整内存大小,减少io次数)

innodbpoolsize可以提高索引命中

mysql并发参数的调整

maxconnection 默认151(需要工具操作系统和硬件的条件决定)

数据库的锁 myisam支持的是表锁,所以再写比较多的场景,并发很低

查看表的使用和被锁的情况 show open tables;

show status like 'table_locks%';(可以查看锁争抢的情况)

innodb的开销大枷锁慢,但是锁的粒度低

mysql的事务是重复读,也就是在同一个事务的数据,多次读取的结果是相同的

mysql有四种日志: 错误日志:路径查找(show variable like 'log_error%';)默认开启 (var/lib/mysql/host)

,二进制日志(binglog),包含ddl,dml语句,不包含查询语句,mysql的主从复制使用 statment是语句

row记录的是行的变化

mimxed集成了statment 和 row

查询日志,记录数据库所有的语句执行,需要手动开启

系统优化 日志模块的优化(分页的优化,总数优化,查询条件优化,读写分离优化,内存优化)

count(*)的优化,维护到一张表中,每次增加,都更新这张表

先通过id主键排序,获取最后的分页数据,再通过id获取表的数据

aop实现数据库切换 读写分离,springaop提供了 Abstrctroutingdatasource方法,自定以数据库的切换

通过solr或者eleserach来实现全文检索,非关系型数据库mogodb

mycat实现集群中间件

,查询日志,慢查询日志

1、需求设计层面

2、系统架构层面

增加缓存机制,大的文件使用、写的sql语句是否高效

3、数据库优化 编写sql需要减少io和全表扫描

表的设计,可以适当冗余,

show variables like '%slow_query%';

开启慢查询日志 set global slow_query_log=on;

设置慢查询时间

SET GLOBAL long_query_time = 1

使用jmeter进行压力测试

使用mysql自带的mysqldumpslow统计慢查询情况

对于简单的语句查看相对容易,但是信息没有 pt-query-digest 的统计全面

pt-sumary可以查看服务器的信息

pt-diskstats命令可以查询mysql的环境信息,包括引擎,磁盘开销,数据库的集群情况

pt-query-digest工具,实质上,是对慢查询日志的一个统计功能

pt-query-digest 慢查询日志路径

这个命令可以查看慢查询的统计信息

每条慢查询的信息,包括执行的次数,每次执行的时间,时间的占比,锁表的时间,每条语句的执行时间的分布图

主要看的是执行次数,执行时间,锁表时间,扫描的数据和发时数据的比row send 和row exam,这三个指标决定了系统的而整体性能

重点 关注的语句

1、查询次数多,查询时间长的语句

row examws是扫描的行数多,io开销大

对比row eaxam和send 判断语句的索引命中高不高

这条命令控制了统计的是慢查询日志的多少的信息

查看数据库的集群信息

查看mysql死锁的问题

将死锁放入到这张表

找出重复的索引

查询io

比较配置文件的差异

查出表大于1m的表

杀掉查询时间大于3秒的进程

explaint对语句的分析

explaint对语句: id列 数据库按id由大到小去执行

select_type 简单的查询是simple;有关联查询,最外层是primary,下面的是union 物化只针对大表

table

type列(重要)

小记,左关联查询的时候,左边是驱动表,右表是被驱动表,需要做左表进行全表扫描,原则上,小表当驱动表,这样,扫描的时长就降低,每条右表,都要拿去匹配左表

创建全文索引,并加上解析器

全文索引的使用

全文索引器的配置信息,

慢查询的优化思路和案例

第一个情况,也就是高并发的sql,是需要优化的

定位优化对象的性能瓶颈,(io问题,是否全表扫描,cpu分组,排序,计算,网络带宽)

明确优化目标:数据库性能,用户体验

explain入手,查看执行计划(只是查看,执行的计划,需要自己想好)

小记,关联查询就是相当于两张表做for循环,小表放外面,大表放里面,大表建索引,就可以很好地i提高性能

尽可能用索引排序

每个sql建议不要超过三张表

对于多表的查询,可以先单表查出来,返回到服务器,在执行下一条语句,这样分步去执行

下面的这三种情况,让他们走索引,这样就不需要额外的缓冲区和临时文件

1、使用小结果集驱动大结果集(join结果集小于百万级别)

inner join 的驱动表,由mysql在决定

被驱动表的关联字段需要增加索引

先在被驱动的索引找,如果有数据,再回表

也就是内嵌套加索引

join buffer是再被驱动表的关联字段没有建立索引的时候,会被使用到,他相当于多线程去执行

排序的时候,使用到了非索引列(extra字段体using filesort)

当使用索引条件查询的时候,使用索引长度小的较好,而且尽量使用较少的索引去查出数据,因为?

如果排序的字段没有加上索引,会使用临时文件,增加了额外的物理io

如果使用多列索引,那么需要有最左原则

需要经过两步io,分别是将排好序的文件,固化代磁盘(也就是oder by的内容以及id),将磁盘里排好序的内容的主键id去寻找表中对应的数据与排好序的内容合并(如果select出来的字段,没有在固化的文件中,这也叫回表),还需缓冲区的大小默认是256k

可以设置拍寻的内容大小

使用group by 的时候,where的条件和group by 需要在一个索引里面,也就是使用联合索引,不然会产生临时表

B树索引,这个数据是存放在磁盘中的,每次查找,都需要通过io,将一个节点的数据读取到内存,cpu计算以后,再io读取下一个节点,知道找到了数据,再返回给客户端

B树的缺点是,当数据量增大时,一个节点可以在很深的位置,需要经过多次的io进行查找,从而提高了查询的成本

B+树 数据都存放在叶子节点,那么上层的节点,在一次的io中,就可以获取更多的key,减低树的高度,从而减少了io的次数,mysql的B+树,还增加了数据末尾端的指针连接,从而提高了范围查询的效率

聚集索引和辅助索引:聚集索引的叶子节点存放了索引的数据,索引当找到了叶子节点,也就获得了表的对于的数据;辅助索引的叶子节点只维护了主键id,还需要主键id回表查找

因为每次增加,索引树都会产生裂变,产生io

为什么使用or条件时,会索引失效

mybatis插入大量的数据

索引的这是尽量选择小的,因为小的索引,每次的io可以加载更多的io

使用union来替代or union all替代 union

垂直拆分主要就是将常用的数据和少用的数据分成两张表,提高io、

对存储引擎数据结构的理解,对表的存储引擎的选择非常重要

索引的分类