mysql文章方案解读与补充
一些mysql文章方案解决与补充分享
目录
主从
主从解决数据库单点故障问题,支持读写分离方案。从库复制主库binlog到relaylog中继日志并重放得到同步数据。注意读写分离配置后,从库可能存在延时,在写入数据后又马上需要读取时的场景。
优化
数据库的优化,一般从慢查询开始,我们先学会慢查询日志的配置,拿到慢查询sql语句后,通过explain进行分析,然后对sql进行调整或索引上的优化,最后explain及验证。
该文图文结合简单易懂的介绍了多种join的方式,inner join,left join,right join,full outer join等。大部分开发过程中用到最多的也都是inner join和left join,而且大多开发在使用上没有问题,问题在于性能上,后面有关于join的优化文章。
这是阿里丁奇老师mysql实战45讲的34讲,主要介绍了join是如何工作的,到底我们能不能用join,另外35讲介绍的是join如何去优化,在34讲中,我们了解了join的原理,我们就懂得如何去优化join语句。
join可以用,但要考虑语句的扫描行数,决定执行效率。优化器会自动判断选择适合的join驱动表。
在35讲中join的优化,主要介绍Multi-Range Read 优化 (MRR)。这个优化的主要目的是尽量使用顺序读盘。
文章最后的小结是精华部分,有利于开发组织高效正确的sql语句实现:
如果你只需要结果集中的某几行,那么建议使用limit。这样的话可以避免抓取全部结果集,然后再丢弃那些你不要的行。
如果limit row_count 与 order by 一起使用,那么在找到第一个row_count就停止排序,直接返回。
对于order by查询,带或者不带limit可能返回行的顺序是不一样的。
如果order by列有相同的值,那么MySQL可以自由地以任何顺序返回这些行。换言之,只要order by列的值不重复,就可以保证返回的顺序。
可以在order by子句中包含附加列,以使顺序具有确定性。
索引
索引本应该放在优化章节里,我们认为索引是一块很重要的部分,基本上所有优化都会是围绕着索引,所以我们将索引单独一章。如果没有特别指出,以下都以innodb为默认引擎。
索引概念、B+树索引、主索引树、普通索引树、聚簇索引、非聚簇索引…
该文章从mysql的索引原理、实现到配置及如何优化做了详细的介绍
如果有耐心,我们还是很推荐阿里丁奇老师的mysql实战45讲。
多一篇索引文章,多一次理解,多一次从稍微不同的角度或讲述重新理解索引
这篇文章通过新华字典的示例操作告诉我们什么是索引、联合索引、聚簇索引,这是从宏观的角度去解读索引,上面的文章提到B+树及原理的我们称为微观的解决索引(理解索引的实现理论,而不仅仅是停留在合理性上)
索引优化的一些所谓的军规和范例,值得再一次理解并化为自己所有。更多干货:更多mysql数据库相关知识与优化
mysql优化中,除了慢查询日志,explain是一个很重要的分析工具。更多关于explain的参数说明:高性能mysql笔记-62、explain扩展
事务
mysql服务器架构、什么是事务、ACID是什么?我们很推荐这篇文章。我们也顺带转载了,避免哪天文章被删除了。
日志:redo log保证持久性(解决buff pool可能丢失数据问题)、undo log保证原子性、bin log是mysql服务器层的日志,常用于基于时间点恢复数据(redo log属于innodb引擎层)
隔离性研究的是不同事务之间的相互影响。隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。四种隔离级别:
一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越差。innodb默认可重复度RR隔离级别,加上间隙锁解决了脏读、不可重复读、幻读问题
一致性:是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。
更多:明明白白事务ACID、03-mysql事务隔离、08-事务到底是不是隔离的
事务的文章有不少,其他的就不推荐了,先把这些弄懂,还是推荐丁奇老师的课,不贵还值得,有课程分销二维码,但我们是真诚推荐,就不贴了,搜索下就有丁奇老师的课。
在以前没有很多框架的年代,新手开发都会被告知注意SQL注入。对于SQL注入这样的词汇,和现在框架里常提到的依赖注入这样的词汇一样,很难让新手理解,老鸟们又喜欢总说一些高度抽象或概念化的词汇,又不进一步说明,让新手捉摸不透。文中介绍了布尔盲注、时间盲注等方式。
总之用户的输入是不可信的,永远记住这点,不论使用什么开发语言或工具场景,永远要对用户输入数据进行处理,才能进一步用于sql查询,当然现在大部分框架已经处理都很好了。
实例方案
有人考虑的读写方案。
文章应该是java系的开发提供的,数据切分方式,切分带来的问题,及如何解决这些问题,什么时候去做切分,用案例来验证以上理论方案。理论同样适用于php。
简单介绍了方案
前面作者通过折腾优化mysql的方案,罗列了很多mysql从设计到开发到优化每个环节要注意的一些细节知识点,基本可以在《高性能MySql》这本书里可以找到,或者简单阅读高性能mysql笔记;文中第二种方案是作者考虑第三方能力更强可兼容mysql的数据库,如阿里云的POLARDB、oceanbase,腾讯云的DCDB等
这篇文章,推荐出来,不是因为他写的很好(虽然很好),而是想说我们获取知识的途径有二:实践和书本。百万数据量分页查询的解决方法就是通过索引及主键id条件快速定位、延迟关联查询方案,为什么呢什么原理?这个在很多mysql书籍,比如《高性能MySql》都有提及,或者简单阅读高性能mysql笔记中:46、优化limit分页,而本文确实从实践中一步一步去摸索,没有谈到每次试验结论的原理,虽然精神可嘉,但行动不可取(可能作者是已经知道原理后,反推写的文章,我们打下自己的脸)。我们推荐可以从书本或前人经验获取的知识,不需要亲自从无到有学习(类似机器学习通过训练集得到原理公式,然后拟合测试集,但你有机器的GPU高速计算能力吗?)
作者不仅精神可嘉,实际行动很踏实,做了很多开发者平常能做但不敢想的事情,也验证了mysql千万及亿级数据库的各种可能性,毕竟这种经验在书本上很难找到,不像一些优化方案基本是板上钉钉再结合实际项目逻辑。
文中试验了亿级表的查询、索引查询、条件查询、小数据量查询、大数据量查询、插入数据,最后也考虑分表查询。总结出了一些结论,这些结论也都验证了mysql的一些原理:大数据表索引是要的,适合条件是可取的有用的,结果范围越大速度越慢,插入数据是要更新索引的从而影响写入速度,分表分库是降低数据库压力的一个大杀器
这篇文章说了几个分库分表路由策略:(java都是用中间件,php还在手动写路由类)
- 中间变量 = user_id % (分库数量 * 每个库的表数量)
- 库 = 取整数 (中间变量 / 每个库的表数量)
- 表 = 中间变量 % 每个库的表数量
讲的更清晰的,方案更复杂一点的分库分表方案。
前面有一篇文章的作者在一个表中写入1亿条数据,数据占用空间将近8G,20亿这个概念有点大,另外mysql官方及高性能MySql中提到表记录达到4、5千万没有问题,更简单的表且进一步优化可以达到1~2亿,这20亿单表没见过。
看来分页优化问题很热门。文中说的方法在高性能MySql中称为延迟关联。
面试知识点
适合mysql新手碎片时间看看,多看看,看几遍,心中有素,实践中适当应用,熟能生巧,不求完全记住,但求大概知道