#SQL#

MySQL性能优化与索引策略

EXPLAIN 

MySQL会根据配置文件会限制server接受的数据包的大小。如果写入大数据时,因为默认的配置太小,插入和更新操作会因为 max_allowed_packet 参数限制,而导致失败。

gh-ost

添加一条和张三一样的数据,但是名字改李四
insert into table (name,data)(select '李四',data from table where  name='张三', )

两段锁2PL:如果两个事务同时尝试写入同一个对象,则锁可确保第二个写入必须等到第一个写入完成事务(中止或提交),然后才能继续,两段锁类似,但使锁的要求更强,只要没有写入,就允许多个事务同时读取同一个对象,但对象只要有写入(修改或删除)就需要独占访问权限例1,如果事务A读取了一个对象,并且事务B想要写入该对象,事务B必须等事务A提交或中止。例2,如果事务A写入了一个对象,并且事务B想要读取该对象,则B必须等A提交或中止才能继续。

2PL和快照隔离的区别:2PL写不仅会阻塞其他写入也会阻塞读,反之亦然,快照隔离使得读不阻塞写,写也不阻塞读,2PL提供了可序化的性质,可以防止竞争条件,包括丢失更新和写入偏差。

实现两阶段锁,MySQLInnoDB的可序化隔离级别。

两阶段提交涉及多次节点间的网络通信,通信时间太长!

事务时间相对于变长了,锁定的资源的时间也变长了,造成资源等待时间也增加好多!

正是由于分布式事务存在很严重的性能问题,大部分高并发服务都在避免使用,往往通过其他途径来解决数据一致性问题。比如使用消息队列来避免分布式事务

XA事务:MySQL中基于XA实现的分布式事务

线性一致性和顺序一致性:分布式系统一致性 - Kaiyuan's Blog | May the force be with me

一致性:强一致性、顺序一致性、弱一致性和共识_chao2016的博客-优快云博客_强一致性

分区:MySQL性能优化(六):分区_monday的博客-优快云博客

复合索引:复合索引的优点和注意事项 - summer0space - 博客园

数据库优化:MySQL性能优化的21个最佳实践 和 mysql使用索引_我是guyue,guyue就是我O(∩_∩)O-优快云博客

or的效率为O(n),而in的效率为O(logn)

SQL语句进行left join时导致的索引失效案例

https://segmentfault.com/a/1190000023072397

书写sql语句时各关键字的顺序: 
select 
from 
where 
group by 
having 
order by

执行顺序: 
from 
where 
group by 
having 
select 
order by

自动转换导致索引失效,从而使锁的级别从行锁升级为表锁

优化

①尽可能让所有数据都通过索引来完成,避免无索引行升级为表锁。

②合理设计索引,尽量缩小锁的范围。

③尽可能使用较少的检索条件,避免间隙锁。

④尽量控制事务大小,减少锁定资源量和时间长度。

⑤尽可能降低事务隔离级别。

①最佳左前缀法则。

#1.在等值查询时,更改索引列顺序,并不会影响explain的执行结果,因为mysql底层会进行优化。

#2.在使用order by时,注意索引顺序、常量,以及可能会导致Using filesort的情况。

②group by容易产生Using temporary。

③通俗理解口诀:

   全值匹配我最爱,最左前缀要遵守;

   带头大哥不能死,中间兄弟不能断;

   索引列上少计算,范围之后全失效;

   LIKE百分写最右,覆盖索引不写星;

   不等空值还有or,索引失效要少用。

MySQL排序优化总结

最后整理一下优化MySQL排序的手段

  1. 排序和查询的字段尽量少。只查询你用到的字段,不要使用select *;使用Limit查询必要的行数据;
  2. 要排序或者查询的字段,尽量不要用不确定字符函数,避免MySQL直接分配max_sort_length,导致sort buffer空间不足;
  3. 使用索引来优化或者避免排序;
  4. 增加sort_buffer_size大小,避免磁盘排序;
  5. 不得不使用original排序算法时,增加read_rnd_buffer_size
  6. 字段长度定义合适就好(避免过长);
  7. tmpdir建议独立存放,放在高速存储设备上

数据库军规

  • 尽量不在数据库做运算。
  • 控制单表数据量。(纯int不超过1000W,含char不超过500W)
  • 保持表身段苗条。(表字段少而精)
  • 平衡范式与冗余。
  • 拒绝大SQL,大事务,大批量。

字段类

  • 用好数值字段类型。
  • 将字符转化为数字。
  • 优先使用枚举ENUM/SET
  • 避免使用NULL字段(很难进行查询优化,NULL列加索引,需要额外空间,含NULL复合索引无效)
  • 少用并拆分TEXT/BLOB
  • 不在数据库里存图片

索引类

  • 谨慎合理添加索引(改善查询,减慢更新,索引不是越多越好)
  • 能不加的索引尽量不加(综合评估数据密度和数据分布,最好不超过字段数的20%)
  • 结合核心SQL优先考虑覆盖索引。
  • 字符字段必须建前缀索引。
  • 不在索引列做运算。
  • 自增列或全局ID做InnoDB主键。
  • 尽量不用外键。

SQL类

  • SQL语句尽可能简单,大SQL拆成多条简单SQL(一条大SQL会吧整个数据库堵死,简单SQL缓存命中率高,减少锁表时间,用上多CPU,一条SQL只能在一个CPU运算)
  • 保持事务(连接)短小(用完即关,减少锁资源占用)
  • 尽可能给你避免使用存储过程,触发器,函数处理
  • 尽量不用select * (会消耗CPU,内存,IO,网络带宽)只取需要数据列。
  • 改写or为in (or效率On,in效率OLogn)注意in个数小于200,
  • 不同字段将or改写为union
  • 避免负向查询(not,!=,not in等)和%前缀模糊查询(使用不了索引导致全表扫描)
  • 减少count(*),(资源开销大)
  • 1.如果在开发中确实需要用到count()聚合,那么优先考虑count(*),因为mysql数据库本身对于count(*)做了特别的优化处理。

    有主键或联合主键的情况下,count(*)略比count(1)快一些。 
    没有主键的情况下count(1)比count(*)快一些。 
    如果表只有一个字段,则count(*)是最快的。
    2.使用count()聚合函数后,最好不要跟where age = 1;这样的条件,会导致不走索引,降低查询效率。除非该字段已经建立了索引。使用count()聚合函数后,若有where条件,且where条件的字段未建立索引,则查询不会走索引,直接扫描了全表。 
    3.count(字段),非主键字段,这样的使用方式最好不要出现。因为它不会走索引

  • limit分页(Limit 10000,10.偏移量越大越慢,推荐where id>=12345 limit 11#10+1(每页10条))
  • 分解连接保证高并发(高并发不建议两个表以上的join)
  • group by去除排序(自动排序)
  • 同数据类型的列值比较(数字对数字,字符对字符where nuber=1 and char='1')
  • 打散大批量更新(凌晨操作避开高峰)

约定类

  • 隔离线上线下
  • 禁止未经DBA确认的子查询上线
  • 永远不再程序端显示加锁
  • 统一字符集UTF8
  • 统一命名规范

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值