`

【MySQL】大表优化

阅读更多

当MySQL单表记录数太多时,各项操作性能会明显下降。

相关优化策略有很多,但肯定不是所有策略都适合某个特定案例。也许在技术层面上,很多策略都能提高性能,但我们也得考虑成本和收益(ROI)。

另,是否有性能提升,或者说从整体业务角度而言综合性能表现是否更符合需求,需要经过实战测试才能确定。

 

此文仅提供几种常见优化方案。对于某些遗留项目【其它方案】中提及的途径可能更合适 —— 优化SQL语句和索引,甚至设计表结构。

 

1. 限制数据范围

通过限定数据操作的范围可以有效减少数据量。
现实业务中需要一次获取大量数据记录的场景其实是比较少的。如,对于查找账单的需求,可以按月份查找,而非一次性获取所有账单。

 

2. 缓存数据

缓存一般适合数据改动频率较低的场景。如果改动频繁,就没有缓存的意义,还会为了维护缓存而增加过多开销。
在具体业务场景链路中哪些位置设置缓存也需要认真考量。持久层框架(如,MyBatis)、应用服务层、Web页面、浏览器客户端都可以做缓存。

 

注意:MySQL的查询缓存从5.6开始默认是关闭的,在5.7.20中被“deprecated”,在8.0中被移除。因为MySQL的查询缓存实现中用到了全局互斥锁,所以会降低性能(无法有效发挥多核服务器的优势)。

 

未认真考量缓存对业务的影响,特别是缓存失效时如何更新数据,是大多数新手会犯的典型错误。这种情况在新手写的应用服务层代码中出现频率较高。


建议:永远不要单人作战引入缓存机制。必须向产品经理等领导详细推演展示缓存机制的影响,确保相关干系人心中有素。认真听取老手的建议,切不可犯蠢。


在实际项目中,拍板做决定的人理解相关细节的影响是非常重要的。我见过一个案例中,产品组内掌握话语权的人集体“犯蠢/宕机”,未听取专家建议,在没有任何缓存失效应对方案的情况下使用缓存,结果在用户环境暴露重大缺陷,最后彻底弃用缓存。“将熊熊一窝”、“统帅无能,累死三军”说的就是这类情况。

 

3. 读写分离

写主库,读从库

 

这种方案适用于 读操作 远多于 写操作的情况,而且需容忍读操作所得数据不是最新数据的情况。

 

How to Setup MySQL (master-slave) Replication in CentOS 7

How to Set Up Master Slave Replication in MySQL

Replication and Binary Logging Options and Variables

 

4. 表分区

表分区是一种特殊的 水平拆分 方式,也是一种特殊的 库内分表

它可以 缓解 单一表数据量过大 的问题,

但它对于减轻数据库服务器压力的作用不大,所有请求还是在争用同一服务器的资源

 

MySQL 的 InnoDB 分区表就是典型代表。其优缺点:

优点

  • 方便对数据分而治之

    • 可以通过删除分区来删除无用的数据。
    • 为新增数据新开分区可以加快执行效率。
    • 可以对分区单独优化、检查、修复、备份、恢复。
  • 提高数据查询效率

    可通过查询条件排除不符合条件的分区,提高效率。

 

缺点

  • InnoDB 分区表不支持外键
    分区表不能引用其它表中的列作为外键;
    其它表不能引用分区表中的列作为外键。
  • 不支持全文索引(Fulltext Index)。
  • 不支持空间类型数据(如,Point、Geometry)。
  • 分区索引不支持子查询

 

5. 垂直拆分

注:垂直拆分后单表数据量未变,依然很大(需要水平拆分)。

 

垂直分库

优点:可以用 不同数据库 支撑不同的业务,降低单个数据库的压力

缺点

  • 上层业务需额外处理不同的数据源
  • 可能存在数据一致性维护问题

 

垂直分表

优点

  • 表结构简化,易于维护
  • 单行数据量变小,一个数据块可存放更多行数据,可减少IO次数

缺点

  • 管理额外的主键冗余列
  • 事务处理复杂
  • 需要额外的表连接操作(join)。可在业务服务器join,减少数据库压力。

 

6. 水平拆分

优点不存在单表数据量过大 和 请求高并发 的性能问题,提高了系统的负载能力 和 稳定性

 

缺点

  • 数据分片的事务一致性难以解决
  • 跨节点 Join 的逻辑复杂,性能差
  • 数据多次扩展 的 难度 和 维护量 非常大

 

7. 其它方案

出于各种原因,与上面那些方案相比,这些方案的普适性可能会更小一点。像“优化SQL语句” 和 “优化索引” 可能在遗留项目中更适用。

甚至 重新设计表结构 是最佳方案,既优化数据库读写性能,又可以重构上层过时的业务逻辑。

 

7.1 使用更紧凑的数据类型

更紧凑的数据类型可以减少对存储空间的需求,读写开销也会更小。如:

  • 不要让单表包含太多字段。
  • 用 TINYINT 等占用空间更小的类型替代 INT。对于无负数的情况,还可将其设置为 Unsigned。
  • 【谨慎】用 ENUM 或 整型 替代字符串类型。
    因为 ENUM降低了可扩展性,整型降低了可读性。如,用整型存储IP就是牺牲了可读性。
  • 【谨慎】使用 TIMESTAMP 替代 DATETIME。
    因为 TIMESTAMP 虽然可减少所需存储空间,但放弃了时区信息(被统一为UTC),且存取数据需要额外的时区转换操作。

我遇到过一个项目,用UUID作为主键。

UUID的正常显示格式是带有连接号(-)的。如,“1ccaf0bc-46fd-11e9-b210-d663bd873d93”。

业务不需要显示连接号,所以生成UUID时会去除连接号。

存储时将通过MySQL的 unhex() 方法 将其转换为二进制;读取时通过 hex() 方法转换为16进制数字串;字段类型为 binary(16),比 char(32) 更节省空间。

 

7.2 优化索引

索引的优化也是非常需要大规模多场景实战性能测试的。很多时候会展现出令人沮丧的结果——还不如“优化”前快。

  • 索引(尽可能)恰到好处

    可根据 WhereOrder By 语句中涉及的字段建立索引。用 Explain 命令查看查询语句用了索引还是全表扫描。
    重复值过多的字段也不适合建索引。
    索引过多,消耗的存储空间越多,维护开销也多,MySQL在判断使用哪个索引时也更耗时(每次查询只能用一个索引)。

  • 多列索引的使用需注意查询条件是否能启用该索引。多列索引通常由于拆分的单列索引。如果所查字段都在多列索引内,可以减少读取操作。
  • 【谨慎】用自增字段作为主键。通常应选取具有实际业务意义的字段作为主键。
  • 【谨慎】不使用 外键、UNIQUE 等约束,由上层业务程序提供保障。

 

7.3 优化SQL语句

优化SQL语句是个大话题,内容繁杂。SQL语句的小技巧很多。如,使用 in 而不是 or;对连续值使用 between 而不是 in。

此外还需要非常了解业务。新工程中SQL语句不合适的情况较少。而对于遗留的数据库,特别是原本业务就复杂的情况,很可能会因表结构设计不合理,导致SQL语句逐渐演变性能越来越差。

 

关于慢查询分析。
慢查询日志(slow_query_log)是最常被提及的方式。但是这种方式非常繁琐。前期准备工作麻烦。为了运行分析工具 mysqldumpslow 还要装 perl。各种变量的设置容易出错,打断工作流程。各项步骤对人很不友好。
通过MySQL Workbench 使用 Performance Schema 方便多了。

 

7.4 使用不同类型的数据库

某些场景确实无法发挥出 MySQL InnoDB 的优势。

对于读密集的场景 MyISAM 因可能更有性能优势。

有些数据也不适合用关系型数据库存储。可以考虑一些NoSQL数据库。

如,日志、监控数据、非结构化 或 弱结构化的数据、对事务和关联操作支持要求较低的数据 等。

 

7.5 升级硬件

这个方案往往会被认为没有技术含量。但很多时候却真的是很值得考虑的方案。
通过收集服务器性能指标,结合业务进行分析,得出恰当的硬件升级方案也不是件容易的事。

 

 

 

分享到:
评论

相关推荐

    MySQL大表性能优化方案 和 MySQL高性能表设计规范

    本篇文章将深入探讨针对MySQL大表的性能优化策略以及如何遵循高性能的表设计规范。 一、MySQL大表性能优化方案 1. **分区表**:当单个表的数据量过大时,可以采用分区技术,将数据分散到多个物理存储单元,提高...

    一次MySQL两千万数据大表的优化过程,三种解决方案!

    如何优化大表数据,是许多开发者和 DBA 都需要面临的问题。本文将详细介绍 MySQL 大表优化过程,包括三种解决方案,并对每种方案进行详细的分析。 问题概述 在实际应用中,我们经常遇到一些大表数据,例如用户记录...

    浅谈MySQL大表优化方案

    阿里云RDS FOR MySQL(MySQL5.7版本)数据库业务表每月新增数据量超过千万,随着数据量持续增加,我们业务出现大表慢查询,在业务高峰期主业务表的慢查询需要几十秒严重影响业务 方案概述 一、数据库设计及索引优化 ...

    最全的MySQL大表优化方案

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万...

    mysql Join使用以及优化

    4. 考虑适当分批处理大表的Join操作,特别是在高并发情况下,以减少资源争用。 总之,合理使用和优化MySQL中的Join操作需要综合考虑表结构、索引设计、查询需求和硬件资源等多方面因素。通过实践和反复调优,DBA和...

    MySQL架构执行与SQL性能优化 MySQL高并发详解 MySQL数据库优化训练营四期课程

    MySQL架构执行与SQL性能优化-MySQL高并发详解课程,课程的目标简单明确,核心就是MySQL的性能优化与高并发。课程内容进行了精华的浓缩,有四大内容主旨,MySQL架构与执行流程,MySQL索引原理详解,MySQL事务原理与...

    mysql性能优化.pptx

    - **水平拆分**(分区):将大表分成多个小表,通过分区策略分散查询负载。 5. **系统级配置优化** - **数据库系统配置**:调整系统参数,如打开文件数、缓冲池大小、线程缓存等,以适应数据库的工作负载。 - **...

    MySQL数据库查询优化

    第12课 表扫描与连接算法与MySQL多表连接优化实践 MySQL的单表扫描算法。MySQL的两表连接算法。MySQL的多表连接算法。 MySQL的多表连接的优化技巧。 预计时间1小时 第13课 查询优化的综合实例(一)------TPCH实践...

    mysql优化笔记+资料

    1. 使用JOIN操作时,确保ON条件是被索引的列,并且在可能的情况下,将JOIN顺序调整为小表先于大表。 2. 减少子查询,尽可能用JOIN替换,因为子查询通常效率较低。 3. 避免在SELECT语句中使用*,明确指定需要的列,...

    大型门户网站核心技术-Mysql优化

    教程名称:大型门户网站核心技术-Mysql优化 课程目录:【】Mysql优化 资料【】Mysql优化01关键技术【】Mysql优化02表的设计【】Mysql优化03慢查询(一)【】Mysql优化04慢查询(二)【】Mysql优化05慢查询(三)【】Mysql...

    MYSQL优化-一篇很好的优化文章

    18. MYSQL行类型(专指IASM/MYIASM表) 19. MYSQL缓存 20. MYSQL表高速缓存工作原理 21. MYSQL扩展/优化-提供更快的速度 22. MYSQL何时使用索引 23. MYSQL何时不使用索引 24. 学会使用EXPLAIN 25. 学会使用...

    千金良方:MySQL性能优化金字塔法则.docx

    MySQL性能优化金字塔法则 MySQL性能优化是指通过调整MySQL数据库的配置、优化数据库结构和查询语句等方式,提高MySQL数据库的性能和响应速度,以满足应用程序的需求。MySQL作为最流行的开源数据库之一,被广泛应用...

    mysql5.6性能优化

    - **分区表**:对于大数据量的表,可以考虑使用分区技术来提高查询效率。 - **存储引擎的选择**:不同的存储引擎适用于不同的应用场景,例如InnoDB支持事务处理,而MyISAM则更适合读密集型的应用。 #### 五、优化...

    2G内存的MYSQL数据库服务器优化

    ### 2G内存的MySQL数据库服务器优化 在IT行业中,对于资源有限的环境进行数据库优化是一项挑战性工作,尤其是在仅有2GB内存的情况下对MySQL数据库服务器进行优化。这种优化旨在提高性能的同时确保系统的稳定运行。 ...

    mysql性能的优化

    3. **分区技术**:使用分区技术将大表分割成多个小表,提高查询效率。 4. **归档旧数据**:定期归档旧数据,减轻数据库负担。 #### 五、优化MySQL服务器 1. **内存配置**:合理设置MySQL服务器的内存使用,如...

    mysql优化配置大全

    mysql慢可能是配置不对,阅读一下这个可能对你有帮助 ...对于Discuz!... 下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化,二是MySQL自身(my.cnf)的优化。

Global site tag (gtag.js) - Google Analytics