> 本质上,TiDB是一个分布式的MySQL。
> 所以,先总结一下MySQL基本理解。
[TOC]
# 索引
## 索引优化
[如何对MySQL索引进行优化分析](https://zhuanlan.zhihu.com/p/71719831)
## 索引数据结构
[干货:mysql索引的数据结构](https://www.jianshu.com/p/1775b4ff123a)
**MyISAM/InnoDB存储引擎都用B+树,但是存储结构不同:**
* MyISAM数据文件和索引文件分离,叶子结点的Key是数据的地址,所以到了叶子,要根据地址查数据;
* InnoDB,主键的索引文件,叶子结点存储的就是数据;非主键索引,叶子结点存储的是主键的Key,所以对于InnoDB,主键索引特别快,因为只要B+树查一遍,而非主键索引慢一点,因为到叶子后,还要再查一遍主键索引。
**通过这个结构的不同,我们也可以理解:**
* 为什么InnoDB必须主键而MyISAM不强制主键。
* 为什么InnoDB不建议使用过长的主键,因为会使辅助索引变得过大。
* 为什么InnoDB不建议非单调的字段做主键,因为插入时维持B+数需要频繁分裂,而自增就比较好一点。
**B树和B+树最大的区别:**
B+树叶子结点才有RowID(指向数据的指针),这样在同样数据的情况下,可以有更少的层级,减少磁盘IO。
## 索引建立耗时经验数据
机器配置:28G内存,SSD硬盘;
数据10G,索引12G,总计耗时:58分钟。
# MyISAM和InnoDB的区别
[Mysql 中 MyISAM 和 InnoDB 的区别有哪些?](https://www.zhihu.com/question/20596402)
**区别:**
InnoDB支持事务。
InnoDB支持外键。
InnoDB是聚集索引,MyISAM是非聚集索引。
MyISAM保存表的具体行数。
InnoDB锁的最小力度是行锁,MyISAM是表锁,并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一。
**如何选择:**
需要事务,只能用InnoDB。
绝大多数都是读,可以考虑MyISAM;读写都频繁,请用InnoDB。
系统奔溃后,MyISAM恢复起来更困难。
5.5之后,InnoDB是默认的,如果不知道如何选择,请用InnoDB。
# 表空洞
Delete操作并不会减小数据表的占用空间:
[Mysql 表空间和 数据页空洞](https://blog.csdn.net/qq_28018283/article/details/85003657)
[页面存储不联系对性能的影响](https://segmentfault.com/q/1010000020223717)
这是因为不会物理删除磁盘空间,除非整页删除(Page是Innodb存储的最基本结构,也是Innodb磁盘管理的最小单位)。
![](https://img.kancloud.cn/2e/98/2e98a3446ce9e1bf52ca400969f87613_1484x1166.jpg)
**如何删除表空洞:**
alter table xxx engine='InnoDB'
db平台会建立新表,数据拷贝完毕,进行表名,所以这个操作耗时是和剩余数据量相关的。
[详谈 MySQL Online DDL](https://www.cnblogs.com/mysql-dba/p/6192897.html)
**删除表空洞经验执行时长:**
机器配置:28G内存,SSD硬盘;
剩余10G数据,6G索引,耗时38分钟。
# Binlog
[Mysql数据库之Binlog日志使用总结(必看篇)](https://blog.51cto.com/xiaocao13140/2126128)
purge master logs before '2019-10-29 00:00:00'
清除150G日志,任务耗时5秒。因为就是删文件。DB平台一般是1G一个Binlog文件,而DBA会限制最多50个Binlog,避免打爆磁盘。
# 性能瓶颈数据参考
**2017.11.23压测:**
多功能一起压测,很快DB出各种异常,各种数据库问题,响应时间高;
单接口压测,压测其中一个慢的接口,getOrderDetail,QPS1000,数据库读QPS 6700,响应50毫秒;
单接口压测,找出最慢的接口,getIncomeSummary,是5万数据中的3万数据Sum,这个接口是当日可用金额,QPS20,就会到2秒,最大11秒,持续压,会拖垮数据库;
**2017年来自DBA的经验数据:**
你们多少台业务机器,连接池这个要看你们业务机器数,这个数据库的最大连接数是2K,只要不超过这个限制就好。
查询QPS看单条SQL的扫描记录,如果每条SQL查询的记录数在几条到几十条,按线上物理机的那种配置,可以到16-20K,线上一般考虑2倍容量,查询可以到8-9K。
写入QPS的话,看是否需要考虑从库延迟,如果需要考虑从库延迟的话,现在这个数据库5.6,从库同步的经验值大概是3K左右,不过这个也要看具体的写入SQL,如果每条写SQL涉及的记录数和记录都比较简单的话,线上有高的同步效率能够到6-7K。
所以考虑2倍容量,经验值的写入QPS在1-1.5K。
# 分库分表汇总
[数据库分库分表解决方案汇总](https://mp.weixin.qq.com/s/kESm-PLwaTbFgg5gPbX-0A)
# 乐观锁和悲观锁
乐观锁适用在“适度争用”的情况下提高性能,因为没有锁的等待,马上成功,或者失败返回,或者失败重试;在“激烈争用”的场景下,只能用悲观锁。
对于一行记录的更新,MySQL是悲观锁,TiDB(3.0.5)是乐观锁。
# 隔离级别
MySQL和Blade都是RR,不可重复读。