MySQL
索引
B+Tree
平衡树,查找树,所有叶子节点位于同一层
进行查找时首先再根节点进行二分查找,找到一个key所在的指针,然后递归的在指针所指向的节点进行查找,直到查到叶子节点,然后在叶子节点二分查找,找出key所对应的data
插入删除操作会破坏数的平衡性,需要进行分裂、合并、旋转等操作来维护平衡性
与红黑树相比
- B+树的高度更低
- 更适合磁盘访问,节点大小设置和磁盘页大小一致
- 磁盘预读,减少I/O
MySQL索引
索引类型
B+Tree索引
大多数MySQL存储引擎的默认索引类型
有序性保证查找、排序、分组效率更高
可以指定多个列为索引列,多个索引列共同组成键
适用于全键值、键值范围和键前缀(只支持最左前缀)查找
主索引和辅助索引
- 主索引的叶子节点data域记录着完整的数据记录,称为聚簇索引,一个表只能有一个聚簇索引
- 辅助索引的叶子节点域记录着主键的值,因此使用辅助索引要先查到主键的值,再到主索引查数据
哈希索引
O(1)查找,但失去了有序性
- 无法用于排序和分组
- 只支持精确查找,不能用于部分查找和范围查找
InnoDB自适应哈希索引,当某个索引值被使用的非常频繁时,会在B+Tree索引只上再建一个哈希索引,以实现快速的哈希查找
全文索引
- 查找文本中的关键字而不是等值比较
空间数据索引
索引优化
独立的列:索引列不能是表达式的一部分,也不能是函数的参数,否则不会使用索引
多列索引:需要使用多个列作为条件查询时,使用多列索引比使用单列索引性能更好
索引列的顺序:选择性强的索引列放在前面
前缀索引:对于BLOB、TEXT、VARCHAR类型的数据,必须使用前缀索引,只索引开始的部分字符
覆盖索引:索引包含所有需要查询的字段的值
- 索引通常远小于数据行的大小,只读取索引能减少数据访问量
- 一些存储引擎(MyISAM)在内存中只缓存索引,只访问索引可以不使用系统调用
- 对于InnoDB引擎,若辅助索引能够覆盖查询,则无需访问主索引
优点
- 大大减少需要扫描的数据行数
- 帮助服务器避免进行排序和分组,以及避免创建临时表
- 将随机I/O变为顺序I/O
使用条件
对于非常小的表大部分情况下全表扫描更高效(如用来保存配置信息的表)
对于中型大型的表,使用索引的效果非常明显
对于特大型的表,建立和维护索引的代价会随之增长
- 分区
- 分库分表
查询性能优化
使用Explain进行分析
- Select_type:查询类型,如简单查询,联合查询、子查询
- key:使用的索引
- Rows:扫描的行数
优化数据访问
减少请求的数据量
- 只返回必要的列,拒绝无脑select * from…
- 只返回必要的行,使用limit限制返回的数据数量
- 缓存重复查询的数据
减少扫描的行数
- 用索引覆盖查询
重构查询方式
- 切分大查询
- 分解大连接查询(将一个大连接查询分解成对每个表进行
一次单表查询,然后在应用程序中进行关联)
- 让缓存更高效,分解后多个查询,即使一个表发生改变,其他表的缓存仍然可以使用
- 单表查询的结果可能被其他查询用到,减少冗余记录的查询
- 减少锁竞争
- 应用层进行连接,更容易对数据库进行拆分,从而更容易做到高性能和可伸缩
- 查询本身效率提升
存储引擎
InnoDB
- MySQL默认的事务型存储引擎
- 实现了四个标准的事务隔离级别
- 主索引是聚簇索引,在索引中保存了数据,对查询性能很大提升
- 内部做了优化,比如磁盘读取数据时采用可预测性读,自动创建自适应哈希索引,能加快插入操作的插入缓冲区
- 支持真正的在线热备份
MyISAM
- 设计简单,提供了很多特性,如压缩表、空间数据索引
- 不支持事务、不支持行级锁
如果不是特殊特性需要,建议都使用InnoDB引擎
复制
主从复制
binlog线程:负责将主服务器上的数据更改写入二进制日志中
I/O线程:负责从主服务器上读取binlog,并写入从服务器的中继日志(Relay Log)
SQL线程:负责读取中继日志,解析出SQL更改并在从服务器中重放(Replay)
主从复制不是强一致性,只能保证最终一致性
复制模式
异步模式
- 主节点不会主动push binlog,同步不及时
半同步复制
- 主节点只需要接收到一台从节点的返回信息就会commit,否则会等到超时然后切换成异步模式再提交,不保证从节点写入db。减少了数据延迟,响应时间会变长
全同步复制
- 全同步模式是主节点和从节点全部执行了commit并确认才会想客户端返回成功。响应时间最长
读写分离
优点
- 主从服务器负责各自的读写,减少锁竞争
- 增加冗余,提高可用性
中间件
- MySQL-Proxy
- MySQL-Router
- MyCat
binlog的业务应用
数据异构
- 随着业务发展,一些表各个业务都关注,但是对字段的使用场景不同。如订单表,可以通过binlog解析成用户维度的订单信息供用户中心查询、商户维度的订单表供运营管理、审计等
缓存更新
- 客户端更新了数据,缓存还未过期,可以通过binlog获取数据变更,并同步到缓存中
任务分发
- 多个系统依赖同一块重要数据,当数据发生变化需要通知其他系统。可以由调度系统订阅binlog进行相应的任务分发、消息发送
NoSQL
not only sql
KV型
- Redis
搜索型
- ElasticSearch
列式
HBase
- 海量数据存储,数据持久化
- 读写性能好
- 横向扩展再关系型数据库中最方便的之一
- 本身没有单点故障,高可用
- 可存储结构化或半结构化的数据
- 比较重,依赖Hadoop组件,运维成本高
- KV式,条件查询弱
- 不支持分页查询
文档型
- MongoDB