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)
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排序的手段
- 排序和查询的字段尽量少。只查询你用到的字段,不要使用select *;使用Limit查询必要的行数据;
- 要排序或者查询的字段,尽量不要用不确定字符函数,避免MySQL直接分配
max_sort_length
,导致sort buffer空间不足; - 使用索引来优化或者避免排序;
- 增加
sort_buffer_size
大小,避免磁盘排序; - 不得不使用original排序算法时,增加
read_rnd_buffer_size
; - 字段长度定义合适就好(避免过长);
- 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
- 统一命名规范