Bootstrap

【MySQL进阶之路 | 高级篇】优化数据库结构和大表优化

目录结构:

目录

目录结构:

1. 优化数据库结构

1.1 拆分表:冷热数据分离

1.2 增加冗余字段

1.3 优化数据类型

情况1:对整数类型数据进行优化

情况2:既可以使用文本类型也可以使用整数类型的字段,要选择使用整数类型

1.4 优化查询记录的速度

A. MyISAM引擎的表

1. 禁用索引

2. 禁用唯一性检查

B. InnoDb引擎的表

1. 禁用唯一性检查

2. 禁用外键

3, 禁止自动提交

1.5 使用非空约束

1.6 分析表,检查表和优化表


1. 优化数据库结构

一个好的数据库设计方案对于数据库的性能能常常会起到事半功倍的效果。合理的数据库结构不仅仅使数据库占用更小的磁盘空间,而且能使查询速度更快。数据库结构的设计需要考虑数据冗余,查询和更新的速度,字段的数据类型是否合理等多方面的内容。

1.1 拆分表:冷热数据分离

拆分表的思路是,把一个包含很多字段的表拆分为两个或多个相对较小的表。这样做的目的是,这些表中某些字段的操作频率很高(热数据),经常要进行查询或更多操作,而另外一些字段的使用频率却很低(冷数据)。冷热数据分离,可以减少表的宽度。如果放在一个表里,每次查询都要读取大的记录,会消耗较多的资源。

MySQL限制每个表最多存储4096列,并且每一行数据的大小不能超过65535字节。表越宽,把表载进内存缓冲池所占用的内存也就越大,也会消耗更多的IO。冷热数据分离的目的就是:减少磁盘IO;保证热数据的内存缓存命中率。更有效利用缓存,避免读入无用的冷数据。

1.2 增加冗余字段

设计数据表时应尽量遵守范式理论的制约,尽可能减少冗余字段,让数据库设计看起来精致,优雅。但是,合理加入冗余字段可以提高查询速度。

表的规范化程度越高,表与表之间的关系也越多,需要连接查询的情况也越多,尤其在数据量大的情况下,而且需要频繁进行连接的时候,为了提高效率,我们也可以考虑增加冗余字段来减少连接。

1.3 优化数据类型

改进表的设计时,可以考虑优化字段的数据类型。优先选择符合存储要求的最小数据类型。

列的字段越大,建立索引时的所需的空间也就越大,这样一页中所能存储的索引节点的数量也就越少,在遍历时需要的IO次数也就越多,索引的性能也就越差。

具体来说:

情况1:对整数类型数据进行优化

遇到整数类型的字段可以用INT类型。这样做的理由是,INT型的数据有足够大的取值范围,不用担心数据超出范围的问题。对于非负型的数据(比如自增ID,整形IP)来说,要优先使用无符号整型UNSIGNED来存储。因为无符号相对于有符号,同样的字节数,存储的数值更大。

情况2:既可以使用文本类型也可以使用整数类型的字段,要选择使用整数类型

根文本类型数据相比,大整数往往占用更少的存储空间。因此,在存取和比对的时候,可以占用更少的内存空间。所以,在二者皆可用的前提下,尽量使用整数类型,这样可以提高查询效率。

1.4 优化查询记录的速度

插入记录时,影响插入速度的主要是索引,唯一性校验,一次插入记录条数等。根据这些情况可以分别进行优化。这里我们分为MyISAM和InnoDB存储引擎来讲。

A. MyISAM引擎的表

1. 禁用索引

对于非空表,插入记录时,MySQL会根据表的索引对插入的记录建立索引,如果插入大量数据,建立索引就会降低插入记录的速度。为了解决这样情况,可以在插入记录之前禁用索引,数据插入完毕后再开启索引。禁用索引的语句如下:

alter table table_name DISABLE KEYS;

重新开启索引的语句如下:

alter table table_name ENABLE KEYS;

若对于空表批量导入数据,则不需要进行该操作,因为iMyISAM引擎的表是导入数据以后才建立索引的。

2. 禁用唯一性检查

插入数据时,MySQL会对插入的记录进行唯一性检验。这种唯一性校验会降低插入记录的速度。为了降低这种情况对查询速度的影响,可以在插入记录之前禁用唯一性检查,等到记录插入完毕后再开启,禁用唯一性检查的语句如下:

SET UNIQUE_CHECKS=0;

B. InnoDB引擎的表

1. 禁用唯一性检查

插入数据之前执行SET UNIQUE_CHECKS=0;来禁止读唯一性索引的检查,数据导入完毕后再运行开启唯一性检查。这个和上述使用方法一样。

2. 禁用外键

插入数据之前执行禁止对外键的检查,数据插入完毕后再恢复对外键的检查。

3, 禁止自动提交

插入数据之前禁止事务自动提交,数据导入完成后,恢复自动提交。语句如下

set autocommit=0;

1.5 使用非空约束

在设计字段的时候,如果业务允许,建议尽量使用非空约束。这样的好处是:

  1. 在进行比较和计算时,省去要对NULL值字段判断是否为空的开销,提高存储效率。
  2. 非空字段也容易创建索引。因为i索引NULL列需要额外的空间来保存,所以需要占用更多的空间。使用非空约束,就可以节省存储空间。

1.6 分析表,检查表和优化表

MySQL提供了分析表,检查表和优化表的语句。分析表主要是分析关键字的分布,检查表主要是检查表的错误,优化表主要是消除删除或者更新造成的空间浪费。

2. 大表优化

当MySQL单表记录过大时,数据库的CURD性能会明显下降,一些常见的优化措施如下:

2.1 限定查询的范围

禁止不带任何限制数据范围条件的查询语句。

2.2 读/写分离

经典的数据库拆分方案,主库负责写,从库负责读。

1. 一主一从模式:

66071f92a44e42308073cf9c5b5015b2.png

2. 双主双从模式:

2.3 垂直拆分

当数据量达到千万级以上时,有时候我们需要把一个数据库切成多份,放到不同的数据库服务器上,减少对单一服务器的访问压力。

  • 如果数据库中的数据表过多,可以采用垂直分库的方式,将关联的数据表部署在同一个数据库上。
  • 如果数据表中的列过多,可以采用垂直分表的方式,将一张数据表拆成多张表,把经常一起使用的列放到一张表里。

垂直拆分的优点:可以使得列数据变小,在查询的时候减少读取的Block数,减少IO次数。此外,垂直分区可以简化表结构,易于维护。

垂直拆分的缺点:主键会出现冗余,需要管理冗余列,并引起JOIN关联表的操作。此外,垂直拆分也会让事务变得更加复杂。

;