MySQL优化大盘点(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 上一篇文章我们一起探讨了MySQL优化的存储引擎选择,配置参数优化,索引优化等,今天小马就继续接下来的篇幅,来唠嗑一下MySQL优化剩下的一些招式。

表分区

谈起分表可能有些小伙伴还可能没用上,但对于表分区,大部分人应该并不陌生。我们先来看百科多分区表的定义:

分区表是将大表的数据分成称为分区的许多小的子集,类型有FAT16,FAT32,NTFS,exFAT,Ext2/3/4,HFS+,VMFS。另外,分区表的种类划分主要有:range(范围)、list(列表)和hash(散列)分区。划分依据主要是根据其表内部属性。同时,分区表可以创建其独特的分区索引。倘若硬盘丢失了分区表,数据就无法按顺序读取和写入,导致无法操作。

来看一则关于表分区的介绍,小马觉得非常易懂。
image.png

那么MySQL该如何实现表分区?先来看MySQL支持的分区的类型有哪些。

1、RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。常用的比如按某一时间范围分区;

2、LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择;小马比较少用。

3、HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

4、KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

值得一提的是,在以往的经验中通常对用来分区的字段,是整形的则使用hash分区,如PARTITION BY HASH (uId) PARTITIONS 10;是字符串型则使用KEY分区,如PARTITION BY KEY (openid) PARTITIONS 11。一般情况下如果对字符串型的列进行hash分区的话会直接报错。

又到了埋彩蛋的时间了,这里注意到KEY分区为什么是11呢不是10呢?以为有些大神分析,当key分区为合数的时候,会出现散列分布不均匀的问题,所以最好建议是质数分区数。

好了,至于具体如何实现的话,创建表分区语句可以网上一找一大把,这里不再赘述。有一点非常有趣的是,MySQL用于表分区的字段列/键必须在该表的所有唯一索引中(含主键)。这句话什么意思呢?就是用在分区上的键,如果表有主键或者唯一索引存在,则它必须在主键和唯一索引里,是的,你没看错,两个都要在。所以这点在创建表结构的时候要兼顾考虑一下。参看两个例子。
image.png

image.png

为什么呢?因为分区后索引结构发生变化,MySQL不能保证之前索引的唯一,所以要求你妥协,分区键要放唯一索引里组合唯一。这点因为结构有差异和Oracel略有不同。

小马认为分区只是基于在物理结构上的,毕竟有局限性,比如对伸缩扩展比较麻烦。那么接下来看基于逻辑上的分表操作。这种方式在大型架构和分布式中尤为受欢迎,因为分表也便于后续作一些高可用动作。话又说回来,当系统体量没有那么大的情况下,就不要分表了,反而影响性能成为累赘。

分表

分表的法子比较多样灵活,但大致可分为两种。

1、利用merge存储引擎来实现分表

此方法的好处就是只需要处理好表结构和插入逻辑,对于查询逻辑是透明的,虽然被分成了N个表但查询时会自动关联。语句场景参考如下:

2、散列某字段为表索引分表

将表字段其中的某一个唯一标志如openid来哈希作为表前缀来均匀分布,直接将表分为N个。如将user表分10个表,假设根据字段qq字段分表,则将得到user_(qq%10)这样的表名后缀索引0-9十个表,于是逻辑代码根据(qq%10)来决定将操作哪个表。这个法子最简单好用。这里qq号刚好是整形直接取模哈希,那如果是openid字符串呢该怎么处理?这点留给观者思考。

这里的分表自增主键原则上是不受影响的,因为各自代码逻辑也是根据哈希键分开来的,但这里建议使用分布式的ID为好,比如雪花算法。

题外话,这里既然提到哈希,那顺带思考下,哈希冲突的解决方式有哪些呢?比如再哈希法,然后呢?

分表后如何支持 全表的搜索和后台的分页查询。参考:

1 2

主从复制,读写分离,负载均衡

只要服务器安装了mysql proxy或Ameoba软件就可以实现读写分离和负载均衡。小马认为,这可以认为这是服务器实现层面的,也就是中间件自己判断是读还是写自己找到配置的机器,以及自己计算负载自己实现均衡。但在TP框架主从DB配置中似乎主从读写分离的实现是从代码层面实现的,是否有印象呢?

编写合理的SQL

这点我想也是老生常谈了。就是不要写查询效率低的慢查询SQL语句。关于是否有慢查询这点可以配置打开慢查询日志并查看,这里不赘述。

关于效率低下的一些经典行为:

1、尽量避免where语句中对字段进行null判断(表设计的时候就尽量不要NULL值),否则将放弃使用索引而进行全表扫描,如:select id from where num is null;

2、最好不要select *,会导致全表扫描。能不用join表连接就不用,非要用记得join on字段加索引;

3、查询有限数据请加limit;尽量给表设置主键,尽管已经有了唯一索引。

4、尽量避免wherer语句后使用!=或者<>操作符或者or,否则将导致放弃索引而进行全表扫描,这点可以参看导致索引失效的例子。or语句可以用uion语句来替换。

5、in和not in也要慎用,否则会进行全表查找,对于连续的数值,能用between就不要用in。很多时候用exist是代替in是一个好的选择。select num from a where num in (select num from b);用下面语句进行替换:select num from a where exists(select 1 from b where num =a.num);

6、应避免在where子句中对字段进行表达式操作或者对字段进行函数操作,这样导致引擎放弃使用索引而进行全表查询,比如:select id from t where num/2=100;

7、如果开启事务请检查异常或者出错的情况下是否回滚或者提交了事务。

MySQL优化就暂告一段落了,欢迎补充指点。

彩蛋时间:

分库分表后如何解决分页问题?

设计的时候让查询的条件都落在一个表上,无法满足加一个满足条件的冗余表;搞个全量索引二次查询;借助中间件,比如mycat(根据sql找到需要的库表集合查询结果,跟查询单表一样)。

三范式
什么是三大范式:

第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。

第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。

第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF.

三范式主要是针对数据库 字段 设计而言,为了好记,小马归纳总结为:

1、字段值的原子性 :学生ID 姓名 学院班级; 不符合:其中学院班级值非原子性 ;正确:分开两个字段存 学院 班级。

2、字段不要冗余:学生ID 宿舍ID 宿舍名; 不符合:其中宿舍ID和宿舍名冗余;正确: 宿舍名存另一个表,用外键关联来实现。

3、不能有值是与主键间接相关: 学号 姓名 院系名称 院系地址; 不符合:其中院系地址是与主键间接相关的是与院系才是直接相关;正确:学号 姓名 院系ID外键 另一个表:院系ID 院系名称 院系地址。

很多时候为了查询效率等其他原因会牺牲一些范式规范,比如第二范式,这也是允许的,并非必须严格遵循。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
SQL 关系型数据库 MySQL
MySQL慢查询优化、索引优化、以及表等优化详解
本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
MySQL慢查询优化、索引优化、以及表等优化详解
|
24天前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
56 3
|
26天前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
52 1
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
80 9
|
28天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
155 1
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
63 5
|
2月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
82 1
|
2月前
|
缓存 关系型数据库 MySQL
一文彻底弄懂MySQL优化之深度分页
【10月更文挑战第24天】本文深入探讨了 MySQL 深度分页的原理、常见问题及优化策略。首先解释了深度分页的概念及其带来的性能和资源问题。接着介绍了基于偏移量(OFFSET)和限制(LIMIT)以及基于游标的分页方法,并分析了它们的优缺点。最后,提出了多种优化策略,包括合理创建索引、优化查询语句和使用数据缓存,帮助提升分页查询的性能和系统稳定性。
131 1
|
29天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
65 0
|
2月前
|
存储 监控 关系型数据库
MySQL并发控制与管理:优化数据库性能的关键
【10月更文挑战第17天】MySQL并发控制与管理:优化数据库性能的关键
185 0