@

MySQL性能优化

应用开发过程中,由于初期数据量小,开发人员更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,数据库开始显露性能问题,对生产的影响也越来越大,因此我们必须对它们进行优化。

性能优化是通过某些有效的方法提高 MySQL 数据库的性能,主要是为了使 MySQL 数据库运行速度更快、占用的磁盘空间更小。

MySQL性能优化简述

简而言之,性能优化就是在不影响系统能正确运行的前提下,运行速度更快,完成特定功能所需的时间更短。

我们可以通过某些有效的方法来提高 MySQL 数据库的性能,目的是让 MySQL 数据库的运行速度更快、占用的磁盘空间更小。

性能优化包括很多方面,例如优化查询速度、优化更新速度和优化 MySQL 服务器等。通过不同的优化方式达到提高 MySQL 数据库性能的目的。优化数据库是数据库管理员和开发人员的必备技能。

MySQL 数据库的用户和数据非常少时,很难判断数据库性能的好坏。只有当长时间运行,并且有大量用户进行频繁操作时,MySQL 数据库的性能才能体现出来。

  • 例如,一个每天有几万用户同时在线的大型网站,它的数据库性能的优劣就很明显。这么多用户同时连接 MySQL 数据库,并且进行查询、插入和更新的操作。如果 MySQL 数据库的性能很差,很可能无法承受如此多用户的同时操作。另外,如果用户查询一条记录需要花费很长时间,那么用户很难会喜欢这个网站。

因此,为了提高 MySQL 数据库的性能,需要进行一系列的优化措施。一方面是找出系统的瓶颈,提高 MySQL 数据库整体的性能,另一方面需要合理的数据库结构设计和参数调整,来提高用户操作响应的速度,同时还要尽可能节省系统资源,以便系统可以提供更大负荷的服务。

例如,

  • 通过优化文件系统,提高磁盘 I\O 的读写速度;
  • 通过优化操作系统调度策略,提高 MySQL 在高负荷情况下的负载能力;
  • 优化表结构、索引、查询语句等使查询响应更快。

如果 MySQL 数据库中需要进行大量的查询操作,那么就需要对查询语句进行优化。对于耗费时间的查询语句进行优化,可以提高整体的查询速度。如果连接 MySQL 数据库的用户很多,那么就需要对 MySQL 服务器进行优化。否则,大量的用户同时连接 MySQL 数据库,可能会造成数据库系统崩溃。

系统的分析效率低下的 SQL 两种方法:

使用 SHOW STATUS 命令

数据库管理员可以使用 SHOW STATUS 语句查询 MySQL 数据库的性能参数,了解各种 SQL 的执行频率。语法形式如下:

SHOW STATUS LIKE 'value';

其中,value 参数是常用的几个统计参数,常用参数介绍如下:

  • Connections:连接 MySQL 服务器的次数;
  • Uptime:MySQL 服务器的上线时间;
  • Slow_queries:慢查询的次数;
  • Com_select:查询操作的次数;
  • Com_insert:插入操作的次数,对于批量插入操作,只累加一次;
  • Com_update:更新操作的次数;
  • Com_delete:删除操作的次数。

以上参数针对于所有存储引擎的表,下面几个参数只针对 InnoDB 存储引擎。

  • Innodb_rows_read:表示 SELECT 语句查询的记录数;
  • Innodb_rows_inserted:表示 INSERT 语句插入的记录数;
  • Innodb_rows_updated:表示 UPDATE 语句更新的记录数;
  • Innodb_rows_deleted:表示 DELETE 语句删除的记录数。

比如,需要查询 MySQL 服务器的连接次数,可以执行下面的 SHOW STATUS 语句:

SHOW STATUS LIKE 'Connections';

查询其它参数的方法和以上参数的查询方法相同。

通过以上几个参数,可以很容易的了解当前数据库的应用是以插入为主还是以查询为主,以及各种类型的 SQL 语句的大致执行比例。然后根据分析结果,进行相应的性能优化。

使用慢查询日志

慢查询次数参数可以结合慢查询日志,找出慢查询语句,然后针对慢查询语句进行表结构优化或者查询语句优化。

MySQL 查询分析器

查询是数据库中最频繁的操作,提高查询速度可以有效的提高 MySQL 数据库的性能。

通过对查询语句的分析,可以了解查询语句的执行情况,找出查询语句执行的瓶颈,从而优化查询语句。在 MySQL 中,可以使用 EXPLAIN 和 DESCRIBE 获取 MySQL 执行 SELECT 语句的信息,来分析查询语句

EXPLAIN 语句的基本语法如下:

EXPLAIN SELECT 语句;

“SELECT 语句”参数一般为数据库查询命令,如“SELECT * FROM tb_student”。通过 EXPLAIN 关键字可以分析后面 SELECT 语句的执行情况,并且能够分析出所查询表的一些内容。

EXPLAIN

例子:下面使用 EXPLAIN 语句来分析一个查询语句。代码执行如下:

mysql> EXPLAIN SELECT * FROM tb_student \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb_student
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 7
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.01 sec)

对以上结果中参数说明如下:

  1. id:表示 SELECT 语句的编号,也就是在整个查询中 SELECT 的位置。如果在语句中没子查询或关联查询,只有唯一的 SELECT,每行都将显示 1。否则,内层的 SELECT 语句一般会顺序编号,对应于其在原始语句中的位置。
  2. select_type:表示 SELECT 语句的类型,该参数有以下几个常用的取值:
    • SIMPLE:表示简单查询,其中不包括连接查询和子查询;
    • PRIMARY:表示主查询,或者是最外层的查询语句;
    • UNION:表示连接查询的第二个或后面的查询语句;
    • DEPENDENT UNION:连接查询中的第 2 个或后面的 SELECT 语句,取决于外面的查询;
    • UNION RESULT:连接查询的结果;
    • SUBQUERY:子查询中的第 1 个 SELECT 语句;
    • DEPENDENT SUBQUERY:子查询中的第 1 个 SELECT 语句,取决于外面的查询;
    • DERIVED:导出表的 SELECT(FROM 子句的子查询)
  3. table:表示查询的表;
  4. partitions:
  5. type:表示表的连接类型。该参数有以下几个常用的取值,范围从 NULL 到 ALL。下面按照最佳类型到最差类型排序:
    • NULL:不用访问表或者索引,直接就能得到结果;
    • system:表示表中只有一条记录;
    • const:表示表中有多条记录,但只从表中查询一条记录;
    • eq _ref:类似 ref,表示多表连接时,后面的表使用了 UNIQUE 或者 PRIMARY KEY;
    • ref:表示多表查询时,后面的表使用了普通索引;
    • range:表示查询语句中给出了查询范围,常见于 <、<=、>、>=、between 等操作符;
    • index:表示对表中的索引进行了完整的扫描,MySQL 遍历整个索引来查询匹配的行;
    • ALL:表示对表进行了完整的扫描,MySQL 遍历全表来找到匹配的行。
  6. possible_keys:表示查询中可以使用的索引;
  7. key:表示实际查询中使用到的索引;
  8. key_len:表示索引字段的长度;
  9. ref:表示使用哪个列或常数与索引一起来查询记录;
  10. rows:表示查询的行数;
  11. filtered:MySQL 5.7 版本之前使用 EXPLAIN EXTENDED 时会出现这个字段,MySQL 5.7 版本之后包括 5.7 版本默认就有这个字段。这个字段表示存储引擎返回的数据在 server 层过滤后,剩下多少满足查询记录数量的比例。注意是百分比,不是具体记录数。
  12. Extra:表示查询过程的附件信息。

DESCRIBE

DESCRIBE 语句的使用方法与 EXPLAIN 语句一样,DESCRIBE 语句的语法形式如下:

DESCRIBE SELECT语句;

DESCRIBE 可以缩写成 DESC。

索引对查询速度的影响

索引是数据库优化中最常用也是最重要的手段之一,通过索引可以帮助用户解决大多数的 SQL 性能问题。

多数情况下,查询速度很慢时,加上索引便能解决问题。但也并非总是如此,因为优化不是件简单的事情。但是如果你不使用索引,在许多情况下,尝试通过其它途径来提高性能都纯粹是在浪费时间。应该首先使用索引来最大程度的改善性能,然后再看看是否还有其它有用的技术。

索引提供了高效访问数据的方法,能够快速的定位表中的某条记录,加快数据库查询的速度,从而提高数据库的性能。

如果查询时不使用索引,那么查询语句将查询表中的所有字段。这样查询的速度会很慢。使用索引进行查询,查询语句不必读完表中的所有记录,而只查询索引字段。这样可以减少查询的记录数,达到提高查询速度的目的。

下面通过对比使用索引和不使用索引来分析索引对查询速度的影响。

为了便于读者更好的理解,分析之前,我们先查询一下 tb_students_info 数据表中的记录,SQL 语句和运行结果如下:

mysql> SELECT * FROM tb_students_info;
+----+------+
| id | name |
+----+------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
| 4 | 赵六 |
| 5 | 周七 |
| 6 | 吴八 |
| 7 | 朱九 |
| 8 | 苏十 |
+----+------+
8 rows in set (0.02 sec)

使用 EXPLAIN 分析未使用索引时的查询情况,SQL 语句和运行结果如下:

mysql> EXPLAIN SELECT * FROM tb_students_info WHERE name='张三' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb_students_info
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 8
filtered: 12.50
Extra: Using where
1 row in set, 1 warning (0.00 sec)

由结果可以看到,rows 列的值是 8,说明查询语句扫描了表中的 8 条记录。

注意:没有索引的表就相当于一组无序的行,如果我们想找到某条记录就必须检查表的每一行,看看它是否与那个期望值相匹配。这是一个全表扫描操作,其效率很低,如果表很大,而且仅有少数几条记录与搜索条件相匹配,那么整个扫描过程的效率将会超级低。

在 tb_students_info 表的 name 字段添加索引,SQL 语句和运行结果如下:

mysql> CREATE INDEX index_name ON tb_students_info(name);
Query OK, 8 rows affected (0.14 sec)

使用 EXPLAIN 再次执行上面的查询语句,SQL 语句和运行结果如下:

mysql> EXPLAIN SELECT * FROM tb_students_info WHERE name='张三' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb_students_info
partitions: NULL
type: ref
possible_keys: index_name
key: index_name
key_len: 63
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)

结果显示,rows 列的值为 1,表示这个查询语句只扫描了表中的 1 条记录。创建索引后访问的行由 8 行减少到 1 行,其查询速度自然比扫描 8 条记录快。而且 possible_keys 和 key 的值都是 index_name,这说明查询时使用了 index_name 索引。所以,在查询操作中,使用索引不仅能自动优化查询效率,还会降低服务器的开销。

注意:由于 tb_students_info 表中记录较少,所以在这没有分析运行时间。表中记录多时,运行时间的差异也会体现出索引对查询速度的影响。

MySQL优化数据库结构

一个好的数据库设计方案会对数据库的性能起到事半功倍的效果。合理的数据库结构不仅可以使数据库占用更小的磁盘空间,而且能够使查询速度更快。

数据库结构是否合理,需要考虑是否存在冗余、对表的查询和更新的速度、表中字段的数据类型是否合理等多方面的内容

分解表

有些表在设计时设置了很多的字段,而有些字段的使用频率非常低。这样当这个表的数据量很大时,查询数据的速度就会很慢。我们可以将这些使用频率较低的字段分离出来形成新表。

例子:在 student 数据表中有很多字段,其中 comment 字段用来存储学生的备注信息。

备注信息的内容特别多,但是该字段很少使用。这时就可以分解出另外一个表。分解出的表为 student_comment,表中存储 2 个字段

  • id :id 为学生的学号
  • comment:comment 为学生备注信息

student_comment 的表结构如下:

mysql> DESC `student_comment`;
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| comment | text | YES | | NULL | |
+---------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

如果需要查询某个学生的备注信息,可以使用学号(id)来查询。如果需要将学生的学籍信息与备注信息同时显示,可以使用表连接查询 student 表和 student_comment 表,查询语句如下:

SELECT * FROM student, student_comment WHERE student.id=student_comment.id;

通过以上方法,可以有效的提高 student 表的查询效率。

增加中间表

表连接会降低数据库的查询速度,所以对于经常使用表连接查询的表,我们可以建立中间表来提高查询速度。

首先分析经常需要同时查询哪几个表中的哪些字段,然后将这些字段建立一个中间表,并将原来那几个表的数据插入到中间表中,之后就可以使用中间表来进行查询和统计了。

例子:下面有两个数据表,分别是 student(学生)表和 score(分数)表。这两个表的结构如下:

mysql> DESC student;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| sex | varchar(4) | YES | | NULL | |
| birth | date | YES | | NULL | |
| address | varchar(50) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec) mysql> DESC score;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| stu_id | int(11) | NO | MUL | NULL | |
| c_name | varchar(20) | YES | | NULL | |
| grade | int(11) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

实际应用中,经常需要查询学生的学号、姓名和成绩。对于这种情况,我们可以创建一个 temp_score 表。temp_score 表中存储 3 个字段,分别是 id、name 和 grade。

创建 temp_score 的 SQL 语句如下:

mysql> CREATE TABLE temp_score(
-> id INT NOT NULL,
-> name VARCHAR(20) NOT NULL,
-> grade FLOAT
-> );
Query OK, 0 rows affected (0.00 sec)

然后从 student 表和 score 表中将记录导入到 temp_score 表中。INSERT 语句如下:

INSERT INTO temp_score SELECT student.id, student.name, score.grade
FROM student, score WHERE student.id=score.stu_id;

将这些数据插入到 temp_score 表中以后,可以直接从 temp_score 表中查询学生的学号、姓名和成绩。这样就省去了每次查询时进行表连接,提高了数据库的查询速度。

增加冗余字段

一般情况下,设计数据库时应尽量让表符合三大范式。但是,有时为了提高查询速度,可以有意识地在表中增加冗余字段。

表的规范化程度越高,表与表之间的关系就越多,查询时也就经常需要在多个表之间进行连接查询,而连接操作会降低查询速度。

  • 例如,学生的信息存储在 student 表中,院系信息存储在 department 表中。通过 student 表中的 dept_id 字段与 department 表建立关联关系。

如果要查询一个学生所在系的名称,就必须从 student 表中查找学生所在院系的编号(dept_id),然后根据这个编号去 department 查找系的名称。这个连接查询会浪费很多的时间。因此可以在 student 表中增加一个冗余字段 deptname,用来存储学生所在院系的名称。这样就不用每次都进行连接操作了。

分解表、增加中间表和增加冗余字段都浪费了一定的磁盘空间。从数据库性能的角度来看,增加少量的冗余来提高数据库的查询速度是可以接受的。是否通过增加冗余来提高数据库性能,这要根据 MySQL 服务器的具体要求来定。如果磁盘空间很大,可以考虑牺牲一点磁盘空间。

MySQL优化插入数据速度

在 MySQL 中,向数据表插入数据时,索引、唯一性检查、数据大小是影响插入速度的主要因素。

根据不同情况,可以分别进行优化。

MyISAM 引擎表优化方法

禁用索引

对非空表插入数据时,MySQL 会根据表的索引对插入的记录进行排序。插入大量数据时,这些排序会降低插入数据的速度。为了解决这种情况,可以在插入数据之前先禁用索引,等到数据都插入完毕后在开启索引。

禁用索引的语句为:

ALTER TABLE table_name DISABLE KEYS;

重新开启索引的语句为:

ALTER TABLE table_name ENABLE KEYS;

对于新创建的表,可以先不创建索引,等到数据都导入以后再创建索引,这样可以提高导入数据的速度。

禁用唯一性检查

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

禁用唯一性检查的语句为:

SET UNIQUE_CHECKS=0;

开启唯一性检查的语句为:

SET UNIQUE_CHECKS=1;

使用批量插入

在 MySQL 中,插入多条数据有 2 种方式。第一种是使用一个 INSERT 语句插入多条数据。INSERT 语句的情形如下:

INSERT INTO items(name,city,price,number,picture) VALUES ('耐克运动鞋','广州',500,1000,'001.jpg'),('耐克运动鞋2','广州2',500,1000,'002.jpg');

第二种是一个 INSERT 语句只插入一条数据,执行多个 INSERT 语句来插入多条数据。INSERT 语句的情形如下:

INSERT INTO items(name,city,price,number,picture) VALUES('耐克运动鞋','广州',500,1000,'001.jpg');
INSERT INTO items(name,city,price,number,picture) VALUES('耐克运动鞋2','广州',500,1000,'002.jpg');

一次性插入多条数据和多次插入数据所耗费的时间是不一样的。第一种方式减少了与数据库之间的连接等操作,其速度比第二种方式要快一些。所以插入大量数据时,建议使用第一种方法。

注意:如果能用 LOAD DATA INFILE 语句,就尽量用 LOAD DATA INFILE 语句。因为 LOAD DATA INFILE 语句导入数据的速度比 INSERT 语句的速度快。

InnoDB 引擎表优化方法

禁用索引&禁用唯一性检查

同 MyISAM 引擎相同,插入数据之前先禁用索引,等到数据都插入完毕后在开启索引。

禁用外键检查

使用外键时,在子表中插入一条数据,首先会检查主表中是否有相应的主键值,然后锁定主表的记录,在插入值。相比较,使用外键多了2步操作,速度会慢一些。所以我们可以在插入数据之前禁止对外键的检查,数据插入完成之后再恢复对外键的检查。不多对于数据完整性要求较高的系统不建议使用。

禁用外键检查语句为:

SET FOREIGN_KEY_CHECKS=0;

恢复对外键的检查语句为:

SET FOREIGN_KEY_CHECKS=1;

禁止自动提交

MySQL 的事务自动提交模式默认是开启的,其对 MySQL 的性能也有一定得影响。也就是说如果你插入了 1000 条数据,MySQL 就会提交 1000 次,这大大影响了插入数据的速度。而如果我们把自动提交关掉,通过程序来控制,只要一次提交就可以了。

所以插入数据之前可以先禁止事务的自动提交,待数据导入完成之后,再恢复自动提交操作。

禁止自动提交语句为:

SET AUTOCOMMIT=0;

恢复自动提交语句为:

SET AUTOCOMMIT=1;

优化MySQL服务器

MySQL 中,可以通过两个方面来优化服务器,即硬件和配置参数的优化。通过这些优化方式,可以提高 MySQL 的运行速度。

优化服务器硬件

服务器的硬件直接决定着 MySQL 数据库的性能。例如,增加内存和提高硬盘的读写速度,可以提高 MySQL 数据库的查询、更新的速度。

优化服务器硬件的方法主要有以下几种:

  • 配置较大的内存
  • 配置高速磁盘系统,以减少读盘的等待时间,提高响应速度
  • 合理分布磁盘 I/O,把磁盘 I/O 分散在多个设备上,以减少资源竞争,提高并行操作能力
  • 配置多处理器,MySQL 是多线程的数据库,多处理器可同时执行多个线程

随着硬件技术的成熟,硬件的价格也随之降低。现在普通的个人电脑都已经配置了 8GB 内存,甚至一些个人电脑配置 16GB/32GB/64GB 内存。因为内存的读写速度比硬盘的读写速度快。可以在内存中为 MySQL 设置更多的缓冲区,这样可以提高 MySQL 的访问的速度。如果将查询频率很高的记录存储在内存中,那么查询速度就会很快。

如果条件允许,可以将内存提高。并且选择 my-innodb-heavy-4G.ini 作为 MySQL 数据库的配置文件。但是,这个配置文件主要支持 InnoDB 存储引擎的表。如果使用 8GB 内存,可以选择 my-huge.ini 作为配置文件。MySQL 所在的计算机最好是专用数据库服务器,这样数据库就可以完全利用该机器的资源。

服务器类型分为 Developer Machine、Server Machine 和 Dedicate MySQL Server Machine。其中 Developer Machine 用来做软件开发的时候使用,数据库占用的资源比较少。后面两者占用的资源比较多,尤其是 Dedicate MySQL Server Machine,其几乎要占用所有的资源。

还可以使用多块磁盘来存储数据。这样可以从多个磁盘上并行读取数据,提高数据库读取数据的速度。通过镜像机制可以将不同计算机上的 MySQL 服务器进行同步,这些 MySQL 服务器中的数据都是一样的。

通过不同的 MySQL 服务器来提供数据库服务,这样可以降低单个 MySQL 服务器的压力,从而提高 MySQL 的性能。

优化MySQL参数

和大多数数据库一样,MySQL 提供了很多参数来进行服务器的优化设置。数据库服务器第一次启动时,很多参数都是默认设置的,这在实际应用中并不能完全满足需求,为此数据库管理员要进行必要的设置。

查看性能参数的方法

MySQL 服务器启动之后,可以使用 SHOW VARIABLES 命令查看系统参数,也可称为静态参数。这些参数是系统默认或者 DBA 调整优化后的参数,可以通过 SET 命令或在配置文件中修改。

使用 SHOW STATUS 命令查询服务器运行的实时状态信息,也就是动态参数。便于 DBA 查看当前 MySQL 运行的状态,做出相应优化,不能手动修改。

例子:下面为使用 SHOW VARIABLES 和 SHOW STATUS 命令的实例。

mysql> SHOW VARIABLES LIKE 'key_buffer_size';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| key_buffer_size | 33554432 |
+-----------------+----------+
1 row in set, 1 warning (0.00 sec) mysql> SHOW STATUS LIKE 'key_read_requests';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Key_read_requests | 149 |
+-------------------+-------+
1 row in set (0.01 sec)

设置优化性能参数

在 MySQL 中,有些参数直接影响到系统的性能。我们可以通过优化 MySQL 的参数提高资源利用率,从而达到提高 MySQL 服务器性能的目的。

以下配置参数都在 my.cnf 或者 my.ini 文件的 [mysqld] 组中。

  1. key_buffer_size(针对MyISAM存储引擎):表示索引缓存的大小,这个参数是对 MyISAM 表性能影响最大的一个参数。值越大,索引进行查询的速度越快。

    • 通过检查状态值 key_read_requests 和 key_reads,可以知道 key_buffer_size 的值是否合理。正常情况下,key_reads / key_read_requests 的比例值需小于 0.01。
  2. table_cache(针对MyISAM存储引擎):表示数据库用户同时打开的表的个数。值越大,能够同时打开的表的个数越多。需要注意的是,这个值不是越大越好,因为同时打开的表太多会影响操作系统的性能。
    • 在设置该参数的时候,可以通过 open_tables 和 opened_tables 变量的值来确定该参数的值。open_tables 参数表示当前打开的表缓存数,opened_tables 参数表示曾经打开的表缓存数。
    • 如果 open_tables 的值已经接近 table_cache 的值,且 opened_tables 还在不断变大,则说明 MySQL 正在将缓存的表释放以容纳新的表,此时可能需要加大table_cache 的值。对于大多数情况,比较适合的值如下:
      • open_tables / opened_tables >= 0.85
      • open_tables / table_cache <= 0.95
    • 执行 FLUSH TABLE 操作后,系统会关闭一些当前没有使用的表缓存,因此 FLUSH TABLE 后,open_tables 参数的值会变小,opened_tables 参数的值不会变。
  3. query_cache_size:表示查询缓存区的大小。使用查询缓存区可以提高查询的速度。内存中会为 MySQL 保留部分的缓存区,这些缓存区可以提高 MySQL 的处理速度。可以从以下几个方面考虑如何设置该参数的大小:
    • 查询缓存对 DDL 和 DML 语句的性能的影响
    • 查询缓存的内部维护成本
    • 查询缓存的命中率以及内存使用率等因素
  4. query_cache_type:表示查询缓冲区的开启状态,用于控制查询结果是否放到查询缓存中。这种方式只适用于修改操作少且经常执行相同的查询操作的情况,其默认值为 0。
    • 值为 0 表示关闭;
    • 值为 1 表示开启;
    • 值为 2 表示按要求使用查询缓存区,只有 SELECT 语句中使用了 SQL_CACHE 关键字,查询缓存区才会使用。例如,SELECT SQL_CACHE * FROM student。
  5. max_connections:表示数据库的最大连接数,默认值为 100。参数最大值不能超过 16384,即使超过也以 16384 为准。该参数设置过小的最明显特征是出现“Too many connections”错误。当然连接数也不是越大越好,因为这些连接会浪费内存的资源。
  6. sort_buffer_size:表示排序缓存区的大小。值越大,排序的速度越快。
  7. read_buffer_size:表示为每个线程保留的缓冲区的大小。当线程需要从表中连续读取记录时需要用到这个缓冲区。
  8. read_rnd_buffer_size:表示为每个线程保留的缓冲区的大小,与 read_buffer_size 相似。但主要用于存储按特定顺序读取出来的记录。
  9. innodb_buffer_pool_size:表示 InnoDB 类型的表和索引的最大缓存。值越大,查询的速度越快。但是这个值太大了也会影响操作系统的性能。
  10. 调优参考计算方法:
    • val = Innodb_buffer_pool_pages_data / Innodb_buffer_pool_pages_total * 100%
    • val > 95% 则考虑增大 innodb_buffer_pool_size, 建议使用物理内存的 75%
    • val < 95% 则考虑减小 innodb_buffer_pool_size, 建议设置为:Innodb_buffer_pool_pages_data * Innodb_page_size * 1.05 / (102410241024)
  11. innodb_log_file_size:该参数的作用是设置日志组中每个日志文件的大小。该参数在高写入负载尤其是大数据集的情况下很重要,这个值越大则性能相对较高。最好不要超过 innodb_log_files_in_group * innodb_log_file_size 的 0.75。
  12. innodb_log_files_in_group:该参数用于指定数据库中有几个日志组,默认为2个,因为有可能出现跨日志的大事务,一般来讲,建议使用 3~4 个日志组。
  13. innodb_log_buffer_size:该参数的作用是设置日志缓存的大小,一旦提交事务,则将该缓存池中的内容写到磁盘的日志文件上。该参数的设置在中等强度写入负载以及较短事务情况下,一般都可以满足服务器的性能要求。如果服务器负载较大,可以考虑加大该参数的值。一般缓存池中的内存每秒钟写到磁盘一次,所以设置较大会浪费内存空间,一般设置为 8MB~16MB 就足够了。可以参考 Innodb_os_log_written 的值,如果该值增加过快,可以适当的增加该参数的值。
  14. innodb_flush_log_at_trx_commit:表示何时将缓冲区的数据写入日志文件,并且将日志文件写入磁盘中。该参数有 3 个值,分别为 0、1 和 2。
    • 值为 0 时,表示每隔 1 秒将数据写入日志文件并将日志文件写入磁盘;
    • 值为 1 时,表示每次提交事务时将数据写入日志文件并将日志文件写入磁盘;
    • 值为 2 时,表示每次提交事务时将数据写入日志文件,每隔 1 秒将日志文件写入磁盘。

该参数的默认值为 1,是最安全最合理的值。为了保证事务的持久性和一致性,建议将该参数设置为 1。

参数设置的值要根据自己的实际情况来设置,并不是值越大越好,可能设置的数值太大体现不出优化效果,反而造成系统空间被占用,导致操作系统变慢。合理的配置参数可以提高 MySQL 服务器的性能。需要注意的是,配置完参数以后,需要重新启动 MySQL 服务配置才会生效。

2020重新出发,MySql基础,性能优化的更多相关文章

  1. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  2. MySQL数据库性能优化:表、索引、SQL等

    一.MySQL 数据库性能优化之SQL优化 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础 优化目标 减少 IO 次数IO永远是数据库最容易瓶颈的地 ...

  3. MySQL 数据库性能优化之索引优化

    接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...

  4. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  5. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  6. MySQL数据库性能优化与监控实战(阶段四)

    MySQL数据库性能优化与监控实战(阶段四) 作者 刘畅 时间 2020-10-20 目录 1 sys数据库 1 2 系统变量 1 3 性能优化 1 3.1 硬件层 1 3.2 系统层 1 3.3 软 ...

  7. 1229【MySQL】性能优化之 Index Condition Pushdown

    转自http://blog.itpub.net/22664653/viewspace-1210844/  [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...

  8. 深入理解MySQL开发性能优化.pptx

    深入理解MySQL开发性能优化.pptx,依旧上传baidu pan http://pan.baidu.com/s/1jIwGslS,视频暂未出,培训完成后会更新.

  9. MySQL数据库性能优化的关键参数(转)

    我们在进行数据库管理和开发中经常会遇到性能问题,这就涉及到MySQL的性能优化.通过在网络上查找资料和笔者自己的尝试,我认为以下系统参数是比较关键的: 关键参数一:back_log 要求 MySQL ...

  10. 从数据库、代码和服务器对PHP网站Mysql做性能优化

    数据库优化是PHP面试几乎都会被问到的事情,也是我们工作中应该注意的事情,当然,如果是小网站无所谓优化不优化,网站访问量大了自然会暴漏数据库的瓶颈,这个瓶颈是各方面问题综合导致的,下面我们来做下数据库 ...

随机推荐

  1. ABC E - Active Infants 贪心 dp

    LINK:Active Infants 一个快省选的人 还在写ABC(莫名觉得丢人 不过也无所谓了. 首先考虑 随便一个排列 我们考虑一下其是不是最优的 容易发现如果最大值没有在边界上的话我们直接把它 ...

  2. github 错误

    Push failed: Unable to access 'https://github.com/infoo/Neo4j.git/': The requested URL returned erro ...

  3. 【BZOJ1426】收集邮票 题解 (期望)

    题目:有n种不同的邮票,皮皮想收集所有种类的邮票.唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n.但是由于凡凡也很喜欢邮票,所以皮 ...

  4. NOI Online#1 小记

    虽然只是一个普通的模拟赛,但是毕竟是我第一次参加官方组织的比赛,所以还是写一篇小记纪念一下吧(毕竟经验少,太菜了. 上午一直颓着,随便看了两眼文化课,补了补昨天的化学作业,就当是对明天月考的复习吧(月 ...

  5. 在Spring Boot中动态实现定时任务配置

    原文路径:https://zhuanlan.zhihu.com/p/79644891 在日常的项目开发中,往往会涉及到一些需要做到定时执行的代码,例如自动将超过24小时的未付款的单改为取消状态,自动将 ...

  6. Qt使用MD5加密

    Qt中包含了大部分常用的功能,比如json.数据库.网络通信.串口通信以及今天说的这个MD5加密: Qt中将字符串进行MD5加密其实比较简单,代码如下: #include <QCoreAppli ...

  7. Java日志框架(一)

    在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而言,日志记录是一个非常重要的问题.因此,如何选择一个合适的日志记录框架也 ...

  8. XCTF-WEB-高手进阶区(1-4)笔记

    1:baby_web 题目描述:想想初始页面是哪个 通过Dirsearch软件扫描发现Index.php被藏起来了,访问他便会指向1.php 于是通过Burp修改Get为index.php,然后放入R ...

  9. C语言编译过程以及Windows中的gcc编译程序(通过cmd、记事本)

    C语言的编译过程 1)预处理:宏定义展开.头文件展开.条件编译等,同时将代码中的注释删除,这里并不会检查语法 2)编译:检查语法,将预处理后的文件编译生成汇编文件 3)汇编:将汇编文件生成目标文件(二 ...

  10. 攻防世界-web(进阶)-upload1

    打开链接是一个上传文件的窗口,随便上传一个PDF文件提示必须上传图片,查看源代码,要求必须输入png或jpg格式文件才会上传成功,想到通过修改源代码删除上传限制条件,上传一句话木马,通过中国菜刀进入后 ...