mysql优化过程

大表和小表连接

最好小表是驱动表,减少外部循环   被驱动表字段需要建立索引,加快查询,最后在回表查询

mysql left join 左边所有数据字段,右边可以没有  INNER JOIN内连接连接匹配关系的记录

mysql的性能优化方面经常涉及到缓冲区(buffer)和缓存(cache),mysql通过在内存中建立缓冲区(buffer)和缓冲(cache)来提高mysql性能。对于innodb数据库,mysql采用缓冲池(bufferpool)的方式来缓存数据和索引;对于mylsam数据库,mysql采用缓存的方式来缓存数据和索引。
Mysql查询缓存机制(query cache)简单的说就是缓存sql语句及查询结果,如果运行相同的sql,服务器直接从缓存中提取结果,而不是再去解析和执行sql。而且这些缓存能被所有的会话共享  
Query_cache_type可以是0,1,2,0代表不使用缓存,1代表使用缓存,2代表根据需要使用

缓冲池(buffer pool) sort_buffer_size join_buffer_size 
innodb_buffer_pool_size   数据缓存+索引缓存 IO读写就越少
innodb_buffer_pool_read_requests(表示从内存中读取逻辑的请求数。) / innodb_buffer_pool_reads(表示InnoDB缓冲池无法满足的请求数。需要从磁盘中读取。)   一般是内存的70-80

possible_keys 出现过多(待选)索引 需要判断那个最快花时间
表空间由段(Segment)、区(Extend)、页(Page)、行(Row)组成
普通索引  唯一索引(允许有空值) 主键索引 .组合索引 全文索引
聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续

哈希索引不适用的场景 不支持范围查询
B+  所有查询都要查找到叶子节点,查询性能稳定
每个元素不保存数据,只用来索引,所有数据都保存在叶子节点
且叶子结点本身依关键字的大小自小而大顺序链接
单一节点存储更多的元素,使得查询的IO次数更少。
InnoDB 只在主键索引树的叶子节点存储了具体数据,但是其他索引树却不存具体数据呢,而要多此一举先找到主键,再在主键索引树找到对应的数据!!!!!!  需要节省存储空间

select abc from table;   和    select * from table;   大字段返回不好

在 abc 字段有索引的情况下,mysql 是可以不用读 data,直接使用 index 里面的值就返回结果的。但是一旦用了 select *,就会有其他列需要读取,这时在读完 index 以后还需要去读 data 才会返回结果,这样就造成了额外的性能开销。

select * from information_schema.processlist  查看进程

show PROCESSLIST

首先优化索引 ->  优化sql  -> 多线程优化查询业务优化 -> 主从同步,读写分离 -> es查询  !!!

my.cnf 优化

read_buffer_size = 2M  sort_buffer_size = 8M  join_buffer_size = 8M

1、大量sleep线程会占用连接数,当超过max_connections后,新连接无法再建立,业务不可用;
2、这些sleep线程中,有些可能有未提交事务,可能还伴随着行锁未释放,有可能会造成严重锁等待;
3、这些sleep线程中,可能仍有一些内存未释放,数量太多的话,是会消耗大量无谓的内存的,影响性能。
优化
利用pt-kill或辅助脚本/工具巡查并杀掉无用sleep进程;!!!
利用5.7的新特性,适当设置max_execution_time阈值,消除长时间执行的SQL;   set wait_timeout=60修改。
定期检查show processlist的结果,找到长时间sleep的线程,根据host&port反推找到相关应用负责人,协商优化方案。  为什么没释放呢

默认连接池 Hikari
长连接  数据库连接池  线程池不是一个东西 
创建长连接  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306", "root", "ok");

产生原因  怎么杀死 解决不产生 
怎么建立长连接  就是conn不关闭吗  不是和连接池一样吗 


先两个相似的表union all  然后 两个表在 left join  
left join就是左边的都显示  右边能匹配的就显示 没有就是null

一般处理这种数据大的情况    先筛选!!!而不是直接join!!!
1.大表对小表,先给大表筛出来,!!!!!!在拼接小表(最简单)
2.宽表,把需要的字段拼接进去(效率最高)
3.大表对大表,程序实现(一张表的数据查出来,按照1000个分,另一张表用in查出来组装成map,再次匹配第一张表)最复杂最不喜欢选的。
4.缓存一张表的全部数据到redis,匹配对接另一张表
 

慢查询日志开启
slow_query_log 慢查询开启状态,ON开启,OFF关闭
slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
long_query_time 查询超过多少秒才记录

#该方式数据库重启全部失效,得重新配置
show variables like 'slow_query%';
set global slow_query_log='ON'; 
#set global slow_query_log_file='';
#set global long_query_time=1;
#永久 加入到my.cnf
service mysqld restart

MVCC:多版本并发控制,一种并发控制的方法,实现对数据库的并发访问,非阻塞并发读
当前读:像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,使用索引不锁全表。它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录
快照读:不加锁的非阻塞读
已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,而可重复读隔离级别则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView
3个隐式字段,undo日志 ,Read View 组成版本链!!!

分区:不能使用主键/唯一键字段之外的其他字段分区

https://www.zhihu.com/question/19719997

1.数据库设计和表创建时就要考虑性能
表字段避免null值出现,推荐默认数字0代替null  尽量使用TIMESTAMP(数字)而非DATETIME  用整型来存IP

2.sql的编写需要注意优化  索引并不是越多越好!!!!要维护和占用空间
EXPLAIN  WHERE子句中对字段进行NULL值判断|不做列运算(函数、计算表达式)|OR改写成IN|在WHERE子句中少使用!=或<>
值分布很稀少的字段不适合建索引,例如"性别"这种只有两三个值的字段!!!!
避免select *,将需要查找的字段列出来
引擎MyISAM  InnoDB事务

3.缓存  redis缓存常用的一周一天等

4.分区:在建表的时候加上分区参数,但是底层由多个物理子表组成  EXPLAIN PARTITIONS 
RANGE:连续区间的列值,把多行分配给分区   LIST分区:匹配一个离散值集合中的某个值来进行选择   HASH分区:用户定义的表达式 KEY分区


以下成本较高,代码和事务一致性,多表查询困难 在设计初数据量大就应该考虑吧!!!!
5.读写分离 主从备份

6.分表:垂直拆分和水平拆分

7.分库:建议做个读写分离就行了

8.底层架构 es hbase

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值