11 MySQL之性能优化

01-优化简介

MySQL数据库优化是多方面的,原则是减少系统瓶颈,减少资源的占用,增加系统的反应速度。
1、通过优化文件系统,提高磁盘I\O的速写速度;
2、通过优化操作系统的调度策略,提高MySQL在高负荷情况下的负载能力;
3、优化表结构、索引、查询语句等使查询响应更快。

在MySQL中,可以使用SHOW STATUS 语句查询一些MySQL数据库的性能参数。
语法结构如下:
SHOW STATUS LIKE 'value';
常用的性能参数如下:
· Connections:连接MySQL服务器的次数;
· Uptime:MySQL服务器的上线时间;
· Slow_queries:慢查询的次数;
· Com_select:查询操作的次数;
· Com_insert:插入操作的次数;
· Com_update:更新操作的次数;
· Com_delete:删除操作的次数。

02-优化查询

通过对查询语句的分析,可以了解查询语句的执行情况,找出查询语句执行的瓶颈,从而优化查询语句。
MySQL中提供了EXPLAIN语句和DESCRIBE语句,用来分析查询语句。

EXPLAIN语句的基本语法格式如下:
EXPLAIN [EXTENDED] SELECT select_options
使用 EXPLAIN 关键字,EXPLAIN语句产生附加信息。
select_options 是查询语句的查询选项,包括FROM WHERE 子句等。

执行该语句,可以分析EXPLAIN后面的select语句的执行情况,并且能过分析出所查询的一些特征。
例:
mysql> select * from student;
+------+--------+
| s_id | name   |
+------+--------+
|    1 | liming |
|    2 | wangwu |
|    3 | lisi   |
+------+--------+
3 rows in set (0.04 sec)

mysql> explain select * from student;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

# 1、索引对查询速度的影响
在MySQL中提高性能的一个最有效的方式就是对数据表设计合理的索引。
使用索引可以快速地定位表中的某条记录,从而提高数据库查询的速度。
创建索引:
create index index_name on student(name);

# 2、使用索引查询
索引可以提高查询速度。但并不是带有索引的字段查询时,索引都会起作用。
以下特殊情况索引并没有起作用:
(1)使用LIKE关键字的查询语句
如果匹配字符串的第一个字符为%,索引不会起作用。只有%不在第一个位置,索引才会起作用。
例:
mysql> create index index_name on student(name);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc select * from student where name like '%l';
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> desc select * from student where name like 'l%';
+----+-------------+---------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | student | NULL       | range | index_name    | index_name | 768     | NULL |    2 |   100.00 | Using index condition |
+----+-------------+---------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

(2)使用多列索引的查询语句
MySQL可以为多个字段创建索引。一个索引可以包括16个字段。对于索引,只有查询语句中使用了这些字段中的第1个字段时,索引才会被使用。
创建多列索引:
create index index_id_price on fruits(f_id, f_price);
(3)使用OR关键字的查询语句
查询语句的查询条件中只有or关键字,且前后的两个条件中的列都是索引时,查询中才能使用索引。否则,查询将不使用索引。
# 1、优化子查询
MySQL从4.1版本开始支持子查询,使用子查询可以进行select语句的嵌套查询。
子查询虽然可以查询语句灵活,但执行效率不高。执行子查询时,MySQL需要为内层查询的结果建立一个临时表。
然后外层查询语句从临时表中查询记录。
查询完毕后,再撤销这些临时表。

在MySQL中,可以使用JOIN查询替代子查询。
连接查询不需要建立临时表,其速度比子查询速度要快,如果查询中,使用索引的话,性能会更好。

03-优化数据库结构

数据库结构的设计,需要考虑数据冗余、查询个更新的速度、字段的数据类型是否合理等多方面的内容。

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

# 2、增加中间表
对于需要经常联合查询的表,可以建立中间表以提高查询效率。
通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。

# 3、增加冗余字段
合理地加入冗余字段可以提高查询速度。

# 4、优化插入记录的速度
插入记录时,影响插入速度的主要是索引、唯一性校验、一次性插入记录条数等。以下为优化插入记录速度的方法:
    对于MyISAM引擎的表:
    (1)禁用索引
    对于非空表,插入记录时,MySQL会根据表的索引对插入的记录建立索引。如果插入大量数据,建立索引会降低插入记录的速度。
为了解决这一情况,可以在插入记录之前禁用索引。数据插入完毕后在开启索引。
禁用索引的语句如下:
ALTER TABLE table_name DISABLE KEYS;
其中 table_name 是禁用索引的表的表名。
重新开启索引的语句如下:
ALTER TABLE table_name ENABLE KEYS;
对于空表批量导入数据,则不需要进行此操作,因为MyISAM引擎的表是在导入数据之后才建立索引的。

    (2)禁用唯一性检查
    插入数据时,MySQL会对插入的记录济宁唯一性校验。这种唯一性校验也会降低插入记录的速度。
    为了降低这种情况对查询速度的影响,可以在插入记录之前禁用唯一性检查,等到记录插入完毕后再开启。
禁用唯一性检查的语句如下:
SET UNIQUE_CHECKS = 0;
开启唯一性检查的语句如下:
SET UNIQUE_CHECKS = 1;
    (3)使用批量插入
    插入多条记录时,可以使用一条INSERT 语句插入一条记录或多条记录;同时插入多条语句的速度更快。
    (4)使用 LOAD DATA INFILE 批量导入
   当批量导入数据时,如果能用LOAD DATA INFILE语句,就尽量使用。因为LOAD DATA INFILE语句导入数据的速度比insert语句更快。

    对于InnoDB引擎的表:
    (1)禁用唯一性检查
    插入数据之前执行set unique_checks = 0 来禁止对唯一索引的检查,数据导入完成后再运行 set unique_checks = 1。
    (2)禁用外键检查
    插入数据之前执行禁止对外键的检查,数据插入完成之后再恢复对外键的检查。
    禁用外键检查的语句如下:
    SET foreign_key_checks=0;
    恢复对外键的检查语句如下:
    SET foreign_key_checks=1;
    (3)禁止自动提交
    插入数据之前禁止事务的自动提交,数据导入完成之后,执行恢复自动提交操作。
    禁止自动提交的语句如下:
    set autocommit=0;
    恢复自动提交的语句如下:
    set autocommit=1;
# 5、分析表、检查表和优化表
    分析表主要是分析关键字的分布;
    检查表主要是检查表是否存在错误;
    优化表主要是消除删除或者更新造成的空间浪费。
    (1)分析表
    MySQL中提供了ANALYZE TABLE语句分析表,基本语法规则如下:
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name[, tb1_name]....
LOCAL关键字是NO_WRITE_TO_BINLOG关键字的别名,二者都是执行过程不写入二进制日志,tb1_name为分析表的表名,可以有1个或多个。

使用 ANALYZE TABLE 分析表的过程中,数据库系统会自动对表加一个只读索。
在分析期间,只能读取表中的记录,不能更新和插入记录。
ANALYZE TABLE 语句能够分析InnoDB、BDB和MyISAM类型的表。
例:
mysql> ANALYZE TABLE student;
+-----------------+---------+----------+----------+
| Table           | Op      | Msg_type | Msg_text |
+-----------------+---------+----------+----------+
| test_db.student | analyze | status   | OK       |
+-----------------+---------+----------+----------+
1 row in set (0.01 sec)

    (2)检查表
    MySQL中可以使用CHECK TABLE 语句来检查。CHECK TABLE 语句检查InnoDB和MyISAM类型的表是否存在错误。
    对于MyISAM类型的表,CHECK TABLE 语句还会更新关键字统计数据。
    CHECK TABLE 也可以检查视图是否有错误。
    基本语法结构如下:
    CHECK TABLE  tb1_name [,tb1_name] ... [option] ...
    option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
其中,tb1_name 是表名;option 参数有5个取值,分别是 QUICK | FAST | MEDIUM | EXTENDED | CHANGED。
各个选项的意义是:
· QUICK:不扫描行
· FAST:只检查没有被正确关闭的表
· CHANGED :只检查上次检查后被更改的表和没有被正确关闭的表
· MEDIUM:扫描行,以验证被删除的连接是有效的。
· EXTENDED:对每行的所有的关键字进行一个全面的关键字查找。
option只对MyISAM类型的表有效,对InnoDB类型的表无效。CHECK TABLE 语句在执行过程中也会给表加上只读锁。

    (3)优化表
    MySQL中使用 OPTIMIZE TABLE 语句来优化表。该语句对InnoDB和 MyISAM类型的表都是有。但是,OPTIMIZE TABLE 语句只能优化表中的VARCHAR、BLOB或TEXT类型的字段。
  OPTIMIZE TABLE 语句的基本语法如下:
 OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name[, tb1_name]....

通过 OPTIMIZE TABLE 语句可以消除删除和更新造成的文件碎片。OPTIMIZE TABLE 语句在执行过程中也会给表加上只读锁。

04-优化MySQL服务器

# 1、优化服务器硬件
服务器的硬件性能直接决定着MySQL数据库的性能。
硬件的性能瓶颈直接决定MySQL数据库运行速率和效率。
以下为优化服务器硬件的方法:
(1)配置较大的内存。
(2)配置高速度磁盘系统,以减少度盘等待时间,提高响应速度。
(3)合理分布磁盘I\O,把磁盘分散在多个设备上,以减少资源竞争,提高并行操作能力。
(4)配置多处理器,MySQL是多线程的数据库,多处理器可同时执行多个线程。

# 2、优化MySQL的参数
通过优化MySQL的参数可以提高资源利用率,从而达到提高MySQL服务器性能的目的。
MySQL服务的配置参数都在my.cnf或者 my.ini 文件的[MySQLd]组中。

猜你喜欢

转载自www.cnblogs.com/pgxpython/p/11736553.html