一、SQL 层面调优
1. 性能分析
使用 explain
语句查看 SQL 语句的执行计划相关信息,可以通过查看返回的 可供使用索引、实际使用索引 等信息对 SQL 语句的执行情况进行分析,并进行针对性的优化。
2. 建立、优化索引
-
索引是 SQL 调优最重要的、最有效的方式,恰当的使用索引,可以大幅提升 SQL 的执行效率,让数据库优化器更好优化 SQL 的执行过程。
-
索引并不是越多越好,过多的索引个数,会增加优化器的筛选负担。
-
如果遇到通过一个字段,查询另一个字段的值的情况,可以建立联合索引,来避免数据库回表,优化查询效率。
注意:主键会默认添加至索引中,所以在联合索引中,不需要手动再次添加主键
-
尽可能地避免函数调用,同时要注意隐式的函数调用(隐式数据类型转换),函数调用会强制禁止使用索引,导致索引建立后并不能得到有效的使用。
-
使用索引虽然会在一些场景中,大幅提升查询效率,但也会增加存储消耗,更重要的是,在有数据更新(插入、修改、删除)时,需要对索引进行修改,会大幅降低数据更新效率,所以采用索引必须要慎重考虑。
二、DDL 层面调优
-
尽可能地采用足以容纳数据的最小存储类型,让数据库在执行查询语句的过程中,能够将更多的数据载入内存进行处理。
-
相比于
varchar
,数据库更适合对int
类型的数据进行处理,如果条件允许,可以将IP地址
、时间戳
等数据通过int
或bigint
类型来存储。 -
尽量不要使用
text
类型字段,若必须要使用,且不常需要查询,则可以考虑将其提出到一张数据表中单独存储,并使用关联查询获取。 -
尽可能地使用
not null
标记,这将大大减小采用了innoDB
引擎的负担。 -
若数据库读取需求远大于修改需求,且不是很需要数据库事务提供支持,可以将数据库引擎由默认的
innoDB
更改为MyISAM
,相比于前者,后者提供了更快的数据读取支持。注:
MyISAM
与innoDB
引擎还存在其他差别,需要根据具体业务情况进行选择。 -
在对数据库进行表结构设计时,就要充分考虑到查询性能相关的问题,一句具体的应用场景,基于基本的数据库设计准则,对数据库进行合理的结构设计,在某些时候,可以违背第三范式设计准则,对数据表增加冗余字段,通过数据的冗余存储,来降低联查的频率。
-
针对经常需要进行联查的字段,也可以通过建立中间表的方法,直接从中间表中获取需要联合查询的数据,以此来减少联合查询的频率,提高查询效率。
三、数据库层面调优
1. 分库、分表
当表中数据达到一定数据量时,单次查询遍历全表速度过慢,可以考虑分库分表。
-
分库:
- 在数据量过大,一个数据库无法满足业务查询需求时,需要同时开启多台数据库服务器,同时提供服务,以提高系统的访问载荷。
- 在通常情况下,为了保证数据的一致性,采用 Master/Slave(主/从)模式来构建数据库架构,主库负责修改,从库负责查询。
- 但需要注意的是,一旦采用分库技术,数据库之间相互独立,就不能再依赖数据库自身的主键生成方法,需要使用独立的主键生成工具,生成全局主键,才能避免主键冲突。
- 还需要注意的是,使用分库技术后,数据表之间无法跨数据库联查,所以通常需要两次查询来近似实现联查功能。
- 若系统中涉及到频繁的数据更新操作,可以通过增加数据库服务器的方式解决,但由于数据库服务器通常是成本高昂的高性能服务器,无限扩充服务器数量,从实际上讲并不现实。在这种情况下,更适合引入为高并发、频繁修改设计的高性能内存数据库(redis 等),用内存数据库充当中间件,并定期将内存数据库中的最新数据持久化到数据库中。
-
分表
-
垂直分表
将不常需要查询的数据列单独分出到新表,以此来提高数据库载入内存的数据数量。
-
水平分表
当数据行数过大时,可以通过水平分表,按指定的行数将数据表分开,例如规定 500w 行一张表。
-
四、服务器性能层面调优
通过测试查看造成服务器性能瓶颈的硬件(CPU、内存、磁盘),并对其进行及时升级更换。