MySQL 性能排查思路


原文链接: MySQL 性能排查思路

除了服务器硬件的性能瓶颈,对于 MySQL 系统本身,我们可以使用工具来优化数据库的性能,通常有三种:使用索引,使用 EXPLAIN 分析查询以及调整 MySQL 的内部配置。

mysql 性能优化 - 慢查询分析、优化索引和配置
美团 MySQL 索引原理及慢查询优化
Mysql 反应慢,CPU 占用高的解决办法总结
千万级记录的 Discuz 论坛导致 MySQL CPU 100% 的优化笔记

type all

当需要读取的数据超过一个临界值时,优化器会放弃从索引中读取而改为进行全表扫描,这是为了避免过多的 random disk.

show processlist 语句,查找负荷最重的 SQL 语句

一、查看 Linux 系统性能的常用命令

MySQL 数据库是常见的两个瓶颈是 CPU 和 I/O 的瓶颈。CPU 在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候,磁盘 I/O 瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的时候那么瓶颈就会出现在网络上。Linux 中我们常用 mpstat、vmstat、iostat、sar 和 top 来查看系统的性能状态。

§ mpstat: mpstat 是 Multiprocessor Statistics 的缩写,是实时系统监控工具。其报告为 CPU 的一些统计信息,这些信息存放在 / proc/stat 文件中。在多 CPUs 系统里,其不但能查看所有 CPU 的平均状况信息,而且能够查看特定 CPU 的信息。mpstat 最大的特点是可以查看多核心 cpu 中每个计算核心的统计数据,而类似工具 vmstat 只能查看系统整体 cpu 情况。

§ vmstat:vmstat 命令是最常见的 Linux/Unix 监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的 CPU 使用率,内存使用,虚拟内存交换情况,IO 读写情况。这个命令是我查看 Linux/Unix 最喜爱的命令,一个是 Linux/Unix 都支持,二是相比 top,我可以看到整个机器的 CPU、内存、IO 的使用情况,而不是单单看到各个进程的 CPU 使用率和内存使用率 (使用场景不一样)。

§ iostat: 主要用于监控系统设备的 IO 负载情况,iostat 首次运行时显示自系统启动开始的各项统计信息,之后运行 iostat 将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。

§ sar: sar(System Activity Reporter 系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘 I/O、CPU 效率、内存使用状况、进程活动及 IPC 有关的活动等。

§ top:top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器。top 显示系统当前的进程和其他状况,是一个动态显示过程, 即可以通过用户按键来不断刷新当前状态. 如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。比较准确的说,top 命令提供了实时的对系统处理器的状态监视。它将显示系统中 CPU 最 “敏感” 的任务列表。该命令可以按 CPU 使用。内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。

除了服务器硬件的性能瓶颈,对于 MySQL 系统本身,我们可以使用工具来优化数据库的性能,通常有三种:使用索引,使用 EXPLAIN 分析查询以及调整 MySQL 的内部配置。

二、查询与索引分析方法以及优化方式

在优化 MySQL 时,通常需要对数据库进行分析,常见的分析手段有慢查询日志,EXPLAIN 分析查询,profiling 分析以及 show 命令查询系统状态及系统变量,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。

2.1、性能瓶颈定位

我们可以通过 show 命令查看 MySQL 状态及变量,找到系统的瓶颈:

Mysql> show status ——显示状态信息(扩展 show status like ‘XXX’)

Mysql> show variables ——显示系统变量(扩展 show variables like ‘XXX’)

Mysql> show engine innodb status\G ——显示 InnoDB 存储引擎的状态

Mysql> show processlist ——查看当前 SQL 执行,包括执行状态、是否锁表等

Shell> mysqladmin variables -u username -p password——显示系统变量

Shell> mysqladmin extended-status -u username -p password——显示状态信息

我常用的主要有 show status 和 show processlist。

慢查询日志分析法

慢查询日志开启方法一:在配置文件 my.cnf 或 my.ini 中在 [mysqld] 一行下面加入两个配置参数

log-slow-queries=/data/mysqldata/slow-query.log

long_query_time=2

注:log-slow-queries 参数为慢查询日志存放的位置,一般这个目录要有 mysql 的运行帐号的可写权限,一般都将这个目录设置为 mysql 的数据存放目录;long_query_time=2 中的 2 表示查询超过两秒才记录;在 my.cnf 或者 my.ini 中添加 log-queries-not-using-indexes 参数,表示记录下没有使用索引的查询。

如下:

log-slow-queries=/data/mysqldata/slow-query.log

long_query_time=10

log-queries-not-using-indexes

慢查询日志开启方法二:当然我们也可以通过命令行设置变量来即时启动慢日志查询,这里就不详细介绍啦。

接下来就是打开 log 文件查看得知哪些 SQL 执行效率低下,再进行分析和处理。

explain(执行计划)分析查询

使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。通过 explain 命令可以得到:

– 表的读取顺序

– 数据读取操作的操作类型

– 哪些索引可以使用

– 哪些索引被实际使用

– 表之间的引用

– 每张表有多少行被优化器查询

EXPLAIN 字段:

ØTable:显示这一行的数据是关于哪张表的。

Øpossible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。

Økey:实际使用的索引。如果为 NULL,则没有使用索引。MYSQL 很少会选择优化不足的索引,此时可以在 SELECT 语句中使用 USE INDEX(index)来强制使用一个索引或者用 IGNORE INDEX(index)来强制忽略索引。

Økey_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好。

Øref:显示索引的哪一列被使用了,如果可能的话,是一个常数。

Ørows:MySQL 认为必须检索的用来返回请求数据的行数。

Øtype:这是最重要的字段之一,显示查询使用了何种类型。从最好到最差的连接类型为 system、const、eq_reg、ref、range、index 和 ALL。

system、const:可以将查询的变量转为常量。如 id=1; id 为主键或唯一键.

eq_ref:访问索引,返回某单一行的数据。(通常在联接时出现,查询使用的索引为主键或惟一键)。

ref:访问索引, 返回某个值的数据.(可以返回多行) 通常使用 = 时发生

range:这个连接类型使用索引返回一个范围中的行,比如使用 > 或 < 查找东西,并且该字段上建有索引时发生的情况 (注: 不一定好于 index)。

index:以索引的顺序进行全表扫描,优点是不用排序,缺点是还要全表扫描。

ALL:全表扫描,应该尽量避免。

ØExtra:关于 MYSQL 如何解析查询的额外信息,主要有以下几种:

using index:只用到索引,可以避免访问表。

using where:使用到 where 来过虑数据。不是所有的 where clause 都要显示 using where.。如以 = 方式访问索引。

using tmporary:用到临时表。

using filesort:用到额外的排序.。(当使用 order by v1,而没用到索引时,就会使用额外的排序)。

range checked for eache record(index map:N):没有好的索引。

profiling 分析查询

通过慢日志查询可以知道哪些 SQL 语句执行效率低下,通过 explain 我们可以得知 SQL 语句的具体执行情况,索引使用等,还可以结合 show 命令查看执行状态。

如果觉得 explain 的信息不够详细,可以同通过 profiling 命令得到更准确的 SQL 执行消耗系统资源的信息。

profiling 默认是关闭的,打开方式 :

mysql>set profiling=1;

2.2、索引及查询优化

索引的类型

Ø 普通索引:这是最基本的索引类型,没唯一性之类的限制。

Ø 唯一性索引:和普通索引基本相同,但所有的索引列值保持唯一性。

Ø 主键:主键是一种唯一索引,但必须指定为”PRIMARY KEY”。

Ø 全文索引:MYSQL 从 3.23.23 开始支持全文索引和全文检索。在 MYSQL 中,全文索引的索引类型为 FULLTEXT。全文索引可以在 VARCHAR 或者 TEXT 类型的列上创建。

大多数 MySQL 索引 (PRIMARY KEY、UNIQUE、INDEX 和 FULLTEXT) 使用 B 树中存储。空间列类型的索引使用 R - 树,MEMORY 表支持 hash 索引。

单列索引和多列索引(复合索引)

索引可以是单列索引,也可以是多列索引。对相关的列使用索引是提高 SELECT 操作性能的最佳途径之一。

多列索引:

MySQL 可以为多个列创建索引。一个索引可以包括 15 个列。对于某些列类型,可以索引列的左前缀,列的顺序非常重要。

多列索引可以视为包含通过连接索引列的值而创建的值的排序的数组。一般来说,即使是限制最严格的单列索引,它的限制能力也远远低于多列索引。

最左前缀:

多列索引有一个特点,即最左前缀(Leftmost Prefixing)。假如有一个多列索引为 key(firstname lastname age),当搜索条件是以下各种列的组合和顺序时,MySQL 将使用该多列索引:

firstname,lastname,age

firstname,lastname

firstname

也就是说,相当于还建立了 key(firstname lastname) 和 key(firstname)。

索引主要用于下面的操作:

Ø 快速找出匹配一个 WHERE 子句的行。

Ø 删除行。当执行联接时,从其它表检索行。

Ø 对具体有索引的列 key_col 找出 MAX() 或 MIN() 值。由预处理器进行优化,检查是否对索引中在 key_col 之前发生所有关键字元素使用了 WHERE keypart# = constant。在这种情况下,MySQL 为每个 MIN() 或 MAX() 表达式执行一次关键字查找,并用常数替换它。如果所有表达式替换为常量,查询立即返回。例如:

SELECT MIN(key2), MAX (key2)  FROM tb WHERE key1=10;

Ø 如果对一个可用关键字的最左面的前缀进行了排序或分组 (例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有关键字元素后面有 DESC,关键字以倒序被读取。

Ø 在一些情况中,可以对一个查询进行优化以便不用查询数据行即可以检索值。如果查询只使用来自某个表的数字型并且构成某些关键字的最左面前缀的列,为了更快,可以从索引树检索出值。

SELECT key_part3 FROM tb WHERE key_part1=1;

有时 MySQL 不使用索引,即使有可用的索引。一种情形是当优化器估计到使用索引将需要 MySQL 访问表中的大部分行时。(在这种情况下,表扫描可能会更快些)。然而,如果此类查询使用 LIMIT 只搜索部分行,MySQL 则使用索引,因为它可以更快地找到几行并在结果中返回。

合理的建立索引的建议:

(1) 越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和 CPU 缓存中都需要更少的空间,处理起来更快。

(2) 简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在 MySQL 中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储 IP 地址。

(3) 尽量避免 NULL:应该指定列为 NOT NULL,除非你想存储 NULL。在 MySQL 中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用 0、一个特殊的值或者一个空串代替空值。

设置索引和编写 SQL 语句时应当注意的一些琐碎建议和注意点:

(1) 当结果集只有一行数据时使用 LIMIT 1。

(2) 避免 SELECT *,始终指定你需要的列

从表中读取越多的数据,查询会变得更慢。他增加了磁盘需要操作的时间,还是在数据库服务器与 WEB 服务器是独立分开的情况下。你将会经历非常漫长的网络延迟,仅仅是因为数据不必要的在服务器之间传输。

(3) 使用连接(JOIN)来代替子查询 (Sub-Queries)

连接(JOIN).. 之所以更有效率一些,是因为 MySQL 不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。

(4) 使用 ENUM、CHAR 而不是 VARCHAR,使用合理的字段属性长度。

(5) 尽可能的使用 NOT NULL。

(6) 固定长度的表会更快。

(7) 拆分大的 DELETE 或 INSERT 语句。

(8) 查询的列越小越快。

Where 条件

在查询中,WHERE 条件也是一个比较重要的因素,尽量少并且是合理的 where 条件是很重要的,尽量在多个条件的时候,把会提取尽量少数据量的条件放在前面,减少后一个 where 条件的查询时间。

避免索引无效的集中情况

Ø where 子句的查询条件里有!=,MySQL 将无法使用索引。

Ø where 子句使用了 Mysql 函数的时候,索引将无效,比如:select * from tb where left(name, 4) = ‘xxx’。

Ø 使用 LIKE 进行搜索匹配的时候,这样索引是有效的:select * from tbl1 where name like ‘xxx%’,而 like ‘%xxx%’ 时索引无效。

三、Mysql 内部配置优化

安装 MySQL 后,配置文件 my.cnf 在 /MySQL 安装目录 / share/mysql 目录中,该目录中还包含多个配置文件可供参考,有 my-large.cnf ,my-huge.cnf, my-medium.cnf,my-small.cnf,分别对应大中小型数据库应用的配置。win 环境下即存在于 MySQL 安装目录中的. ini 文件。

下面列出了对性能优化影响较大的主要变量,主要分为连接请求的变量和缓冲区变量。

3.1、连接请求的变量:

1)max_connections

MySQL 的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于 MySQL 会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。

数值过小会经常出现 ERROR 1040: Too many connections 错误,可以通过’conn%’通配符查看当前状态的连接数量,以定夺该值的大小。

show variables like ‘max_connections’  #最大连接数

show  status like ‘max_used_connections’  #响应的连接数

max_used_connections / max_connections * 100% (理想值≈ 85%)

如果 max_used_connections 跟 max_connections 相同,那么就是 max_connections 设置过低或者超过服务器负载上限了,低于 10% 则设置过大。

2)back_log

MySQL 能暂存的连接数量。当主要 MySQL 线程在一个很短时间内得到非常多的连接请求,这就起作用。如果 MySQL 的连接数据达到 max_connections 时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即 back_log,如果等待连接的数量超过 back_log,将不被授予连接资源。

back_log 值指出在 MySQL 暂时停止回答新请求之前的短时间内有多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的 TCP/IP 连接的侦听队列的大小。

当观察你主机进程列表(mysql> show full processlist),发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时,就要加大 back_log 的值了。

默认数值是 50,可调优为 128,对于 Linux 系统设置范围为小于 512 的整数。

3)interactive_timeout

一个交互连接在被服务器在关闭前等待行动的秒数。一个交互的客户被定义为对 mysql_real_connect() 使用 CLIENT_INTERACTIVE 选项的客户。

默认数值是 28800,可调优为 7200。

3.2、缓冲区变量

全局缓冲:

1)key_buffer_size

key_buffer_size 指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。通过检查状态值 Key_read_requests 和 Key_reads,可以知道 key_buffer_size 设置是否合理。比例 key_reads / key_read_requests 应该尽可能的低,至少是 1:100,1:1000 更好(上述状态值可以使用 SHOW STATUS LIKE ‘key_read%’获得)。

key_buffer_size 只对 MyISAM 表起作用。即使你不使用 MyISAM 表,但是内部的临时磁盘表是 MyISAM 表,也要使用该值。可以使用检查状态值 created_tmp_disk_tables 得知详情。

举例如下:

mysql> show variables like ‘key_buffer_size‘;

+——————-+————+

| Variable_name | Value |

+———————+————+

| key_buffer_size | 536870912 |

+———— ———-+————+

key_buffer_size 为 512MB,我们再看一下 key_buffer_size 的使用情况:

mysql> show global status like ‘key_read%‘;

+————————+————-+

| Variable_name  | Value |

+————————+————-+

| Key_read_requests| 27813678764 |

| Key_reads   | 6798830 |

+————————+————-+

一共有 27813678764 个索引读取请求,有 6798830 个请求在内存中没有找到直接从硬盘读取索引,计算索引未命中缓存的概率:

key_cache_miss_rate =Key_reads / Key_read_requests * 100%,设置在 1/1000 左右较好

默认配置数值是 8388600(8M),主机有 4GB 内存,可以调优值为 268435456(256MB)。

2) query_cache_size

使用查询缓冲,MySQL 将查询结果存放在缓冲区中,今后对于同样的 SELECT 语句(区分大小写),将直接从缓冲区中读取结果。

通过检查状态值 Qcache_*,可以知道 query_cache_size 设置是否合理(上述状态值可以使用 SHOW STATUS LIKE ‘Qcache%’获得)。如果 Qcache_lowmem_prunes 的值非常大,则表明经常出现缓冲不够的情况,如果 Qcache_hits 的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;如果 Qcache_hits 的值不大,则表明你的查询重复率很低,这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。此外,在 SELECT 语句中加入 SQL_NO_CACHE 可以明确表示不使用查询缓冲。

与查询缓冲有关的参数还有 query_cache_type、query_cache_limit、query_cache_min_res_unit。

query_cache_type 指定是否使用查询缓冲,可以设置为 0、1、2,该变量是 SESSION 级的变量。

query_cache_limit 指定单个查询能够使用的缓冲区大小,缺省为 1M。

query_cache_min_res_unit 是在 4.1 版本以后引入的,它指定分配缓冲区空间的最小单位,缺省为 4K。检查状态值 Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多,这就表明查询结果都比较小,此时需要减小 query_cache_min_res_unit。

举例如下:

mysql> show global status like ‘qcache%‘;

+——————————-+—————–+

| Variable_name | Value  |

+——————————-+—————–+

| Qcache_free_blocks  | 22756  |

| Qcache_free_memory  | 76764704 |

| Qcache_hits      | 213028692 |

| Qcache_inserts     | 208894227 |

| Qcache_lowmem_prunes | 4010916 |

| Qcache_not_cached | 13385031 |

| Qcache_queries_in_cache | 43560 |

| Qcache_total_blocks | 111212  |

+——————————-+—————–+

mysql> show variables like ‘query_cache%‘;

+————————————–+————–+

| Variable_name      | Value  |

+————————————–+———–+

| query_cache_limit      | 2097152 |

| query_cache_min_res_unit  | 4096   |

| query_cache_size      | 203423744 |

| query_cache_type      | ON  |

| query_cache_wlock_invalidate | OFF  |

+————————————–+—————+

查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

如果查询缓存碎片率超过 20%,可以用 FLUSH QUERY CACHE 整理缓存碎片,或者试试减小 query_cache_min_res_unit,如果你的查询都是小数据量的话。

查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%

查询缓存利用率在 25% 以下的话说明 query_cache_size 设置的过大,可适当减小;查询缓存利用率在 80%以上而且 Qcache_lowmem_prunes > 50 的话说明 query_cache_size 可能有点小,要不就是碎片太多。

查询缓存命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%

示例服务器查询缓存碎片率=20.46%,查询缓存利用率=62.26%,查询缓存命中率=1.94%,命中率很差,可能写操作比较频繁吧,而且可能有些碎片。

每个连接的缓冲

1)record_buffer_size

每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描,你可能想要增加该值。

默认数值是 131072(128K),可改为 16773120 (16M)

2)read_rnd_buffer_size

随机读缓冲区大小。当按任意顺序读取行时 (例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySQL 会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但 MySQL 会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。

一般可设置为 16M

3) sort_buffer_size

每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速 ORDER BY 或 GROUP BY 操作。

默认数值是 2097144(2M),可改为 16777208 (16M)。

4) join_buffer_size

联合查询操作所能使用的缓冲区大小

record_buffer_size,read_rnd_buffer_size,sort_buffer_size,join_buffer_size 为每个线程独占,也就是说,如果有 100 个线程连接,则占用为 16M*100

5) table_cache

表高速缓存的大小。每当 MySQL 访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。通过检查峰值时间的状态值 Open_tables 和 Opened_tables,可以决定是否需要增加 table_cache 的值。如果你发现 open_tables 等于 table_cache,并且 opened_tables 在不断增长,那么你就需要增加 table_cache 的值了(上述状态值可以使用 SHOW STATUS LIKE ‘Open%tables’获得)。注意,不能盲目地把 table_cache 设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。

1G 内存机器,推荐值是 128-256。内存在 4GB 左右的服务器该参数可设置为 256M 或 384M。

6) max_heap_table_size

用户可以创建的内存表 (memory table) 的大小。这个值用来计算内存表的最大行数值。这个变量支持动态改变,即 set @max_heap_table_size=#

这个变量和 tmp_table_size 一起限制了内部内存表的大小。如果某个内部 heap(堆积)表大小超过 tmp_table_size,MySQL 可以根据需要自动将内存中的 heap 表改为基于硬盘的 MyISAM 表。

7)tmp_table_size

通过设置 tmp_table_size 选项来增加一张临时表的大小,例如做高级 GROUP BY 操作生成的临时表。如果调高该值,MySQL 同时将增加 heap 表的大小,可达到提高联接查询速度的效果,建议尽量优化查询,要确保查询过程中生成的临时表在内存中,避免临时表过大导致生成基于硬盘的 MyISAM 表。

mysql> show global status like ‘created_tmp%‘;

+——————————–+———+

| Variable_name   | Value |

+———————————-+———+

| Created_tmp_disk_tables | 21197 |

| Created_tmp_files   | 58  |

| Created_tmp_tables  | 1771587 |

+——————————–+———–+

每次创建临时表,Created_tmp_tables 增加,如果临时表大小超过 tmp_table_size,则是在磁盘上创建临时表,Created_tmp_disk_tables 也增加, Created_tmp_files 表示 MySQL 服务创建的临时文件文件数,比较理想的配置是:

Created_tmp_disk_tables / Created_tmp_tables * 100% <= 25% 比如上面的服务器 Created_tmp_disk_tables / Created_tmp_tables * 100% =1.20%,应该相当好了

默认为 16M,可调到 64-256 最佳,线程独占,太大可能内存不够 I/O 堵塞

8)thread_cache_size

可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性能可以这个变量值。

通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用。

默认值为 110,可调优为 80。

9) thread_concurrency

推荐设置为服务器 CPU 核数的 2 倍,例如双核的 CPU, 那么 thread_concurrency 的应该为 4;2 个双核的 cpu, thread_concurrency 的值应为 8。默认为 8

10)wait_timeout

指定一个请求的最大连接时间,对于 4GB 左右内存的服务器可以设置为 5-10。

3.3、配置 InnoDB 的几个变量

innodb_buffer_pool_size

对于 InnoDB 表来说,innodb_buffer_pool_size 的作用就相当于 key_buffer_size 对于 MyISAM 表的作用一样。InnoDB 使用该参数指定大小的内存来缓冲数据和索引。对于单独的 MySQL 数据库服务器,最大可以把该值设置成物理内存的 80%。

根据 MySQL 手册,对于 2G 内存的机器,推荐值是 1G(50%)。

innodb_flush_log_at_trx_commit

主要控制了 innodb 将 log buffer 中的数据写入日志文件并 flush 磁盘的时间点,取值分别为 0、1、2 三个。0,表示当事务提交时,不做日志写入操作,而是每秒钟将 log buffer 中的数据写入日志文件并 flush 磁盘一次;1,则在每秒钟或是每次事物的提交都会引起日志文件写入、flush 磁盘的操作,确保了事务的 ACID;设置为 2,每次事务提交引起写入日志文件的动作,但每秒钟完成一次 flush 磁盘操作。

实际测试发现,该值对插入数据的速度影响非常大,设置为 2 时插入 10000 条记录只需要 2 秒,设置为 0 时只需要 1 秒,而设置为 1 时则需要 229 秒。因此,MySQL 手册也建议尽量将插入操作合并成一个事务,这样可以大幅提高速度。

根据 MySQL 手册,在允许丢失最近部分事务的危险的前提下,可以把该值设为 0 或 2。

innodb_log_buffer_size

log 缓存大小,一般为 1-8M,默认为 1M,对于较大的事务,可以增大缓存大小。

可设置为 4M 或 8M。

innodb_additional_mem_pool_size

该参数指定 InnoDB 用来存储数据字典和其他内部数据结构的内存池大小。缺省值是 1M。通常不用太大,只要够用就行,应该与表结构的复杂度有关系。如果不够用,MySQL 会在错误日志中写入一条警告信息。

根据 MySQL 手册,对于 2G 内存的机器,推荐值是 20M,可适当增加。

innodb_thread_concurrency=8

推荐设置为 2*(NumCPUs+NumDisks),默认一般为 8

作者:小怪聊职场
链接:https://www.jianshu.com/p/3c79039e82aa
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

`