写在前面,最近比较忙没时间去写,这不,清明放假了,也没有办法回老家,才得以写点东西

类型

myisam

memory

innodb

用途

快读

内存数据

完整的事务与支持


全表锁

全表锁

多种隔离级别的行锁

持久性

基于表恢复

磁盘I/O,无持久性

基于日志恢复

事务特征

不支持

不支持

支持

支持索引

B-tree/FullText/R-tree

Hash/B-tree

Hash/B-tree

MySQL在高并发下的性能瓶颈很明显,主要原因就是锁机制导致的阻塞,而 innodb 采用的是行级别的锁,行级锁消耗要远大于表级锁。但是系统遇到高并发的时候 innodb 的性能要高得多,同时 innodb不仅缓存索引本身还会缓存数据,所以 innodb 需要更大的内存

1-选择合适的存储引擎是优化 mysql 的第一步
ps:读写比:R/W, 执行 show global status; 可得到系统当前的状态,得到一个粗糙的读写比,理想的读写比一般在 100:1 左右,当这个值约为 10:1 的时候就可以认为系统是以写为主了。
选择存储引擎的原则:

场景

采用 myisam引擎

采用 myisam引擎

采用 myisam引擎

读写比

R/W>100:1,且update相对较少

R/W较小且频繁更新

无限制

并发

并发量低不需要事务

高并发、一致性要求高

一致性要求不高,但实时性高

数据量

数据量较小100W以内

数据超千万

无确切数,需要定期归档的数据

硬件资源

资源有限

硬件资源相对充足

硬件资源相对充足

2-MySQL服务器调优
(1)关闭不必要的二进制日志和慢查询日志,仅在内存足够或者开发测试阶段打开
使用 show variables like ‘%slow%’; 查看慢查询是否打开
使用 show global status like ‘%slow%’; 查看慢查询条数
由于慢查询会带来cpu损耗,建议间断性打开慢查询日志来定位瓶颈
(2)适度使用 Query Cache
(3)增加MySQL允许的最大连接数:show variables like ‘%max-connections%’
(4)对MyIsam 适当增加 key-buffer-size ,需根据 key-cache 的命中率进行计算
(5)在表中删除大量的行后,使用optimize table tablename 整理碎片
当然,数据层面的优化通常就是加索引优化查询

3-MySQL瓶颈以及应对
首先明确一点,mysql 肯定是存在瓶颈的,当单表数据达到1000万级别后,无论如何调优,执行一次简单的查询,mysql 的性能都会显著降低。
我们可以考虑从以下几方面优化,优先级降序:
(1) 增加 mysql 配置中的 buffer 和 cache 的值,增加服务器 cpu 和内存,这样很大程度上应对 mysql 性能瓶颈。性能调优中效果最显著成本最低的就是硬件和服务器优化,一般有限考虑这一点,当然前提是系统中的 sql 没有索引问题。
(2) 使用第三方引擎和第三方版本:
如 Percona 在功能和性能上比 MySQL 有显著提升
MariaDB 在 innodb 引擎性能上比 MySQL 更加优秀
TokuDB 性能是 MySQL 的 10 倍以上!
以上3款替代品都是针对 innodb 存储引擎而言的。
PS: innodb 每次提交事务,为保证数据持久化到磁盘,需要调用一次 fsync 告知文件系统,将可能存在缓存中的数据刷新到磁盘上,而 fsync I/O 操作会占用大量资源,响应较慢,若每次事务都 fsync 那么这个又是个瓶颈,于是就有了 group commit 从名字我们可以看出批量提交。但是 MySQL5.0后处于分布式架构考虑为了保证 innodb 和 mysql 日志顺序一致性,innodb 被迫放弃了 group commit
(3) 对数据库进行分区分表操作,减少单表体积
(4) 使用 nosql 等辅助解决方案如 redis mongodb memcache等
(5) 使用数据库连接池
(6) 使用中间件做数据拆分和分布式部署