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、
对存储引擎数据结构的理解,对表的存储引擎的选择非常重要
索引的分类