MySQL优化基本思想

数据库优化一方面是找出系统的瓶颈,提高MySQL数据库的整体性能,而另一方面需要合理的结构设计和参数调整,以提高用户的相应速度,同时还要尽可能的节约系统资源,以便让系统提供更大的负荷。

这里将优化分为三大类:软优化底层优化硬优化。软优化一般是操作数据库即可;而底层优化和硬优化则是操作服务器硬件及参数设置。

软优化

1. 定位慢sql语句

  • 执行 show full processlist; 查看当前的sql进程
  • 执行如下语句,查看自数据库上次启动至今的增删改查统计结果,以确认应用是以插入更新为主,还是查询为主
show global status where variable_name in ('Com_select','Com_insert','Com_update','Com_delete');
  • 修改 my.cnf 开启慢查询记录
slow_query_log = 1                                 #.slow_query_log[={0|1}]选项来启用慢查询日志
long_query_time = 2                                #.所有执行时间超过long_query_time秒的SQL语句都会被记录到慢查询日志。
log_output = file                                  #.设置log_output=table的话,则日志结果会记录到名为mysql.slow_log的表中
slow_query_log_file = /data/mysql_3406/slow.log    #.慢查询的日志文件
  • 执行 show status like 'Slow_queries'; 查看慢查询的次数

2. 分析慢sql语句

可以用 EXPLAIN 或 DESCRIBE(简写:DESC) 命令分析一条查询语句的执行信息。

比如执行 explain SELECT * FROM user; 则会显示索引和查询数据读取数据条数等信息

3. 优化子查询

在MySQL中,尽量使用JOIN来代替子查询。因为子查询需要嵌套查询,嵌套查询时会建立一张临时表,临时表的建立和删除都会有较大的系统开销,而连接查询不会创建临时表,因此效率比嵌套子查询高。

4. 合理使用索引

索引是提高数据库查询速度最重要的方法之一,使用索引的三大注意事项包括:

  • 使用多列索引必须满足最左匹配
  • LIKE关键字匹配'%'开头的字符串,不会使用索引
  • OR关键字的两个字段必须都是用了索引,该查询才会使用索引

5. 字段拆分

对于字段较多的表,如果某些字段使用频率较低,此时应当将其分离出来从而形成新的表。

6. 中间表

对于将大量连接查询的表可以创建中间表,从而减少在查询时造成的连接耗时。

7. 增加冗余字段

类似于创建中间表,增加冗余也是为了减少连接查询。

8. 分析表、检查表、优化表

分析表主要是分析表中关键字的分布;检查表主要是检查表中是否存在错误;优化表主要是消除删除或更新造成的表空间浪费。

  • 分析表:使用 ANALYZE 关键字,比如 ANALYZE TABLE user;
  • 检查表:使用 CHECK 关键字,比如 CHECK TABLE user [option];
  • 优化表:使用 OPTIMIZE 关键字,比如 OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;

底层优化

1. 关闭 numa

  • 关闭numa,会提升 15% ~ 30% 的 QPS

关于如何关闭numa

  • bios级别关闭:在 BIOS 中设置关闭 BIOS:interleave = Disable / Enable
  • grub级别关闭:在 grub 中设置 numa=off
  • 数据库级别关闭:修改启动参数 numactl --interleave=all mysqld_safe --defaults-file=/etc/my.cnf &

2. 关闭 THP

  • 关闭透明大页 THP(Transparent Huge Pages),否则可能会导致内存泄漏swap的使用或内存的严重碎片化

3. 系统层面参数优化

  • 更改文件句柄和进程数 65535
  • 防火墙与SeLinux
  • 文件系统优化,推荐使用xfs文件系统
  • 不适用LVM

硬优化

1. 硬件三件套升级

  • CPU:配置多核心和频率高的cpu,多核心可以执行多个线程;
  • 内存:增加内存,可以减少磁盘I/O时间,从而提高响应速度;
  • 硬盘:配置高速磁盘或合理分布磁盘:高速磁盘提高I/O,分布磁盘能提高并行操作的能力;

2. 优化数据库参数

优化数据库参数可以提高资源利用率,从而提高MySQL服务器性能,下面列出性能影响较大的几个参数:

参数名称 默认设置 推荐设置 描述
sync_binlog - 1 刷binlog的方式,0高性能/1高安全/n兼顾性能和安全
binlog_cache_size 32KB 8M 基于会话的、所有未提交的二进制日志缓存文件大小
innodb_buffer_pool_size 8MB 物理内存的70% innodb保存索引和原始数据的缓冲池大小
innodb_log_file_size - 1024M 日志文件的大小,调大可以提高性能,但也会增加故障恢复所需的时间
innodb_log_buffer_size - 16M 日志文件所用的内存大小,调大可以提高性能,但意外故障将会丢失更多数据
innodb_flush_log_at_trx_commit 1 1 log buffer刷新到磁盘的方式,1最安全/0性能最好/其他值则折衷
innodb_buffer_pool_instances 8或1 8 配置多少个缓存池,建议设置为CPU核数,最大64
sort_buffer_size 256K 2M 执行排序缓存区大小
read_buffer_size 256K 2M 执行查询缓存区大小
join_buffer_size 256K 2M 执行联合查询分配缓存区大小
key_buffer_size - 64M 索引块的缓冲区大小,只针对mysiam
query_cache_size - 0 查询缓冲区大小
query_cache_type - 0 设置query_cache_size的开关,0/1表示禁用/启用缓冲区
max_allowed_packet 4M 实际情况 最大数据集大小,注意会影响到mysqldump
thread_cache_size - 400 线程池缓存大小
max_connections 151 3000 所有用户同时打开的最大连接数
max_user_connections - 2000 每个用户同时打开的最大连接数

更多请参考 MySQL 性能调优和优化资源

3. 读写分离 + 分库分表

若数据库压力过大,首先一个问题就是高峰期系统性能可能会降低,因为数据库负载过高对性能会有影响。

另外一个,压力过大把你的数据库给搞挂了怎么办?

所以此时你必须得对系统做分库分表+读写分离,也就是把一个库拆分为多个库,部署在多个数据库服务上,这时作为主库承载写入请求。然后每个主库都挂载至少一个从库,由从库来承载读请求。

4. 缓存集群

数据库其实本身不是用来承载高并发请求的,通常来说,数据库单机每秒承载的并发就在几千的数量级,而且数据库使用的机器都是比较高配置,比较昂贵的机器,成本很高。如果只是通过简单的加机器来提高并发请求,这个做法其实是不对的。

在高并发架构里通常都有缓存这个环节,缓存系统的设计就是为了承载高并发而生。单机承载的并发量都在每秒几万,甚至每秒数十万,对高并发的承载能力比数据库系统要高出一到两个数量级。你完全可以根据系统的业务特性,对那种写少读多的请求,引入缓存集群

具体来说,就是在写数据库的时候同时写一份数据到缓存集群(比如 redis)里,然后用缓存集群来承载大部分的读请求。这样的话,通过缓存集群,就可以用更少的机器资源承载更高的并发。

结语

一个完整而复杂的高并发系统架构中,一定会包含各种复杂的自研基础架构系统和各种精妙的架构设计,但是总的来说,数据库优化的思想差不多就这些,希望能对大家有所帮助。

Copyright © www.sqlfans.cn 2024 All Right Reserved更新时间: 2024-06-24 11:17:04

results matching ""

    No results matching ""