MySQL性能优化第二弹!数据库结构的优化,梅花香自苦寒来

前言

之前咱们更新MySQL优化查询的学习内容,今天我们继续来学习MySQL优化数据库结构。每天深入一小时,日积月累,大厂就在向你招手!!!

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

将字段很多的表分解成多个表

对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

假设会员表存储会员登录认证信息,该表中有很多字段,如id、姓名、密码、地址、电话、个人描述字段。其中地址、电话、个人描述等字段并不常用。可以将这些不常用字段分解出另外一个表。将这个表取名叫members_ _detail。 表中有member_ jid、address 、telephone、description 等字段。其中,member_ id是会员编号,address 字段存储地址信息,telephone字段存储电话信息,description 字段存储会员个人描述信息。这样就把会员表分成两个表,分别为members表和mermber_detail 表。

创建这两个表的SQL语句如下:

这两个表的结构如下:

如果需要查询会员的详细信息,可以用会员的id来查询。如果需要将会员的基本信息和详细信息同时显示,可以将members表和members_ detail 表进行联合查询,查询语句如下:

SELECT*FROMmembersLEFTJOINmembers_ detailONmembers .

id-members detail.

member_id;

通过这种分解,可以提高表的查询效率。对于字段很多且有些字段使用不频繁的表,可以通过这种分解的方式来优化数据库的性能。

增加中间表

对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。本小节将为读者介绍增加中间表优化查询的方法。

首先,分析经常联合查询表中的字段。然后,使用这些字段建立一个中间表,并将原来联合查询的表的数据插入到中间表中。最后,可以使用中间表来进行查询了。

会员信息表和会员组信息表的SQL语句如下:

查询会员信息表和会员组信息表。

已知现在有一个模块需要经常查询带有会员组名称、会员组备注(remark) 、会员用户名信息的会员信息。根据这种情况可以创建-一个temp_ _vip 表。temp_ vip表中存储用户名(user_ name),会员组名称(group_ name) 和会员组备注( group_ remark) 信息。创建表的语句如下:

接下来,从会员信息表和会员组表中查询相关信息存储到临时表中:

以后,可以直接从temp_ vip 表中查询会员名、会员组名称和会员组备注,而不用每次都进行联合查询。这样可以提高数据库的查询速度。

增加冗余字段

设计数据库表时应尽量遵循范式理论的规约,尽可能减少冗余字段,让数据库设计看起来精致、优雅。但是,合理地加入冗余字段可以提高查询速度。本小节将为读者介绍通过增加冗余字段来优化查询速度的方法。

表的规范化程度越高,表与表之间的关系就越多,需要连接查询的情况也就越多。例如,员工的信息存储在staff表中,部门信息存储在department表中。通过staff表中的department_id字段与department 表建立关联关系。如果要查询一个员工所在部门的名称,必须从staff 表中

查找员工所在部门]的编号(department id),然后根据这个编号去department表查找部门的名称。如果经常需要进行这个操作,连接查询会浪费很多时间。可以在staff 表中增加一个冗余字段deartment. name,该字段用来存储员工所在部门的名称,这样就不用每次都进行连接操作了。

冗余字段会导致一些问题。比如,冗余字段的值在一个表中被修改了,就要想办法在其他表中更新该字段。否则就会使原本一致的数据变得不一致。分解表、增加中间表和增加冗余字段都浪费了一定的磁盘空间。从数据库性能来看,为了提高查询速度而增加少量的冗余大部分时候是可以接受的。是否通过增加冗余来提高数据库性能,这要根据实际需求综合分析。

优化插入记录的速度

插入记录时,影响插入速度的主要是索引、唯- -性校验、 一.次插入记录条数等。根据这些情况,可以分别进行优化。本小节将为大家介绍优化插入记录速度的几种方法。

对于MyISAM引擎的表,常见的优化方法如下:

1、禁用索引

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

ALTERTABLEtablenameDISABLEKEYS;

其中table_ name是禁用索引的表的表名。

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

ALTERTABLEtable_nameENABLEKEYS;

对于空表批量导入数据,则不需要进行此操作,因为MyISAM引擎的表是在导入数据之后才建立索引的。

2、禁用唯一性检查

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

SETUNIQUE_CHECKS=0;

开启唯一性检查的语句如下:

SET3UNIQUE_CHECKS=1;

3、使用批量插入

插入多条记录时,可以使用一条INSERT 语句插入-条记录;也可以使用一-条 INSERT语句插入多条记录。使用一条INSERT语句插入一条记录的情形如下:

使用一条INSERT语句插入多条记录的情形如下:

第2种情形的插入速度要比第1种情形快。

4、使用LOAD DATA INFILE批量导入

当需要批量导入数据时,如果能用LOAD DATA INFILE语句,就尽量使用。因为LOAD DATA INFILE语句导入数据的速度比INSERT语句快。

对于InnoDB引擎的表,常见的优化方法如下:

1、禁用唯一性检查

插入数据之前执行set unique_ checks=0 来禁止对唯一索引的检查, 数据导入完成之后再运行set unique_ checks=1。 这个和MyISAM引擎的使用方法一样。

2、禁用外键检查

插入数据之前执行禁止对外键的检查,数据插入完成之后再恢复对外键的检查。禁用外键检查的语句如下:

SETforeign_key_ checks=0;

恢复对外键的检查语句如下:

SETforeign_key_ checks=l;

3、禁止自动提交

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

setautocommit=0;

恢复自动提交的语句如下:

setautocommit=l ;

分析表、检查表和优化表

MySQL提供了分析表、检查表和优化表的语句。分析表主要是分析关键字的分布:检查表主要是检查表是否存在错误:优化表主要是消除删除或者更新造成的空间浪费。本小节将为大家介绍分析表、检查表和优化表的方法。

1、分析表

MySQL中提供了ANALYZE TABLE语句分析表ANALYZE TABLE语句的基本语法如下:

ANALYZE[LOCAL1 NO_ WRITE TO_BINLOG]TABLEtbl_name[, tbl_name]...

LOCAL关键字是NO_ WRITE_ _TO_ BINLOG关键字的别名,二者都是执行过程不写入二进制日志,tbl_ _name 为分析的表的表名,可以有一个或多个。

使用ANALYZE TABLE分析表的过程中,数据库系统会自动对表加一个只读锁。在分析期间,只能读取表中的记录,不能更新和插入记录。ANALYZE TABLE语句能够分析InnoDB、BDB和MyISAM类型的表。

使用ANALYZE TABLE来分析message表,执行的语句及结果如下:

上面结果显示的信息说明如下:

Table: 表示分析的表的名称。

Op:表示执行的操作。

analyze 表示进行分析操作。

Msg_ type: 表示信息类型,其值通常是状态(status) 、信息(info)、注意( note )警告(warmning) 和错误(error) 之一。

Msg_ text:显示信息。

2、检查表

MySQL中可以使用CHECK TABLE语句来检查表CHECK TABLE语句能够检查InnoDB和MyISAM类型的表是否存在错误。对于MyISAM类型的表,CHECK TABLE语句还会更新关键字统计数据。而且,CHECK TABLE也可以检查视图是否有错误,比如在视图定义中被引用的表已不存在。该语句的基本语法如下:

CHECKTABLEtb1name[,tblname]...[option]...

option = {QUICK1FASTIMEDIUM|EXTENDED1CHANGED}

其中,tbl. name是表名; option 参数有5个取值,分别是QUICK、FAST、MEDIUM、EXTENDED和CHANGED。各个选项的意义分别是:

QUICK: 不扫描行,不检查错误的连接。

FAST: 只检查没有被正确关闭的表。

CHANGED: 只检查.上次检查后被更改的表和没有被正确关闭的表。

MEDIUM:扫描行,以验证被删除的连接是有效的。也可以计算各行的关键字校验和,并使用计算出的校验和验证这一点。

EXTENDED: 对每行的所有关键字进行一个全面的关键字查找这可以确保表是100%一致的,但是花的时间较长。option只对MyISAM类型的表有效,对InnoDB类型的表无效。CHECK TABLE语句在执行过程中也会给表加上只读锁。

3、优化表

MySQL中使用OPTIMIZE TABLE语句来优化表。该语句对InnoDB和MyISAM类型的表都有效。但是,OPTILMIZE TABLE语句只能优化表中的VARCHAR、BLOB或TEXT类型的字段。OPTILMIZE TABLE语句的基本语法如下:

OPTIMIZE[LOCAL|NO_WRITE_TO_BINLOG]TABLEtbL_name [,tblname]...

LOCAL | NO_ WRITE_ TO_ BINLOG 关键字的意义和分析表相同,都是指定不写入二进制日志; tbl_ name是表名。通过OPTIMIZE TABLE语句可以消除删除和更新造成的文件碎片。OPTIMIZE TABLE语句在执行过程中也会给表加上只读锁。

一个表使用了TEXT或者BLOB这样的数据类型,如果已经删除了表的一大部分,或者已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)进行了很多更新,则应使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片。在多数的设置中,根本不需要运行OPTIMIZE TABLE。即使对可变长度的行进行了大量的更新,也不需要经常运行,每周一次或每月一次即可,并且只需要对特定的表运行。

以上就是小编整理的MySQL优化数据库结构,算是MySQL优化的核心内容了,抛砖引玉,只是小编个人的理解,欢迎各位大佬多多讨论交流,咱们共同进步!!!

喜欢小编请多多点赞评论转发,关注小编,每天小编都会有新内容更新学习,希望更好的帮到大家学习~~~

你可能感兴趣的:(MySQL性能优化第二弹!数据库结构的优化,梅花香自苦寒来)