天天看点

mysql 优化 >_MySQL 性能优化之一 重要配置变量优化

原文链接:

key_buffer_size

本节提到的MySQL配置变量:

key_buffer_size

设置索引表可以使用的内存总空间,越大说明会有越多的 MyISAM

表的索引文件*.MYI 保存在内容中。

本节提到的MySQL状态变量:

key_reads

访问索引表的查询访问了硬盘的总次数,特指查询使用的索引表没有放入内存, 不得不去访问硬盘的情况,这个值越小越好。

key_read_requests

访问索引表的查询总次数(包括cache在内存中的索引表和硬盘上的), 这个值和前者的比例越大越好。

The key_buffer_size

is probably the most useful single variable to tweak. The larger you set it,

the more of your MyISAM table indexes you store in memory. With most queries

making use of an index, and memory being an order of magnitude faster than

disk, the importance of this variable cannot be overestimated.

key_buffer_size 可能是最有用的单独的优化变量。设置的越大,将会有越多的MyISAM

索引表存储在内存中。

On dedicated MySQL

servers, the rule-of-thumb is to aim to set the key_buffer_size to at

least a quarter, but no more than half, of the total amount of memory on the

server. Ideally, it will be large enough to contain all the indexes (the total

size of all .MYI files on the server). If you are unable to make it large

enough for this, the best way to fine-tune the setting is to compare the key_reads

and the key_read_requests status variables. The latter is the total

number of requests making use of an index, while the former is the total number

of those requests that had to read from disk. You want at least 100 requests to

every request from disk, preferably a lot more. Have a look at scenario 1, with

the same query run a few seconds apart.

在专用的MySQL服务器上,根据经验设置 key_buffer_size 至少是总内存的1/4,但是

不能超过总内存的一半,完美的情况是,这个值足够大,应该大于所有索引表.MYI文件的

总和。如果你不确定到底多大的值合适,最好的办法是在调整设置时比较

key_reads 和 key_read_requests 这个状态值。

后面的值是使用索引的请求的总数,而前面的值是这些请求中去读磁盘的总次数。

情景分析1:

mysql> SHOW STATUS LIKE '%key_read%';

+-------------------+------------+

| Variable_name | Value |

+-------------------+------------+

| Key_read_requests | 3606100254 |

| Key_reads | 2594030 |

+-------------------+------------+

mysql> SHOW STATUS LIKE '%key_read%';

+-------------------+------------+

| Variable_name | Value |

+-------------------+------------+

| Key_read_requests | 3606102741 |

| Key_reads | 2594030 |

+-------------------+------------+

This is a healthy ratio,

around 1400 to 1. Of the 2500 index requests between the two samples, none

required the disk. On this server, the key_buffer is set to 768M, while

the total memory available is 3GB.

上面显示的情况是比较正常的比例,每 1400 个请求中有 1 个访问磁盘。

这里 key_buffer 设置为 768M,总内存是 3GB.

情景分析2:

mysql> SHOW STATUS LIKE '%key_read%';

+-------------------+-----------+

| Variable_name | Value |

+-------------------+-----------+

| Key_read_requests | 609601541 |

| Key_reads | 46729832 |

+-------------------+-----------+

In scenario 2, it is

shocking, about 13 to 1. On this server, the key_buffer_size was set to

16MB out of 64MB. If you are in a similar situation, it is clear what your next

hardware upgrade should be. RAM is always the primary hardware upgrade you can

do to improve your system.

情形2非常糟糕,请求和磁盘访问的比例为: 13:1, key_buffer_size 设置的是

16M ,系统内存是 64M. 如果你处在同样的情况下,那么非常明显你需要升级硬件增加

系统内存。

The table_cache

本节提到的MySQL设置变量:

table_cache

允许 MySQL

打开的表的最大个数,并且这些都cache在内存中。

本节提到的MySQL状态变量:

Open_tables

打开的表的个数,并这些表在内存cache中。

Opened_tables

累计打开过的表的个数,如果这个值很大并且张的很快,说明

table_cache 设置太小。

The table_cache

remains a useful variable to tweak. Each time MySQL accesses a table, it places

it in the cache. If your system accesses many tables, it is faster to have

these in the cache. One thing to note is that you may have more open tables

than there are database tables on the server. MySQL, being multi-threaded, may

be running many queries on the table at one time, and each of these will open a

table. A good way to see whether your system needs to increase this is to

examine the value of open_tables at peak times. If you find it stays at

the same value as your table_cache value, and then the number of opened_tables starts

rapidly increasing, you should increase the table_cache if you have enough

memory. Look at these three scenarios, during peak times.

每次 MySQL 访问一个表,将会把它放入 cache 中,如果你的系统要访问很多表,

能在cache中访问是非常块的。

有一个情况是你的服务器上有很多打开的表,而且远远大于你的数据库中实际拥有的

表,这是因为MySQL是多线程的,同一时间也许会有很多表被查询,每个线程都会打开

一个表,所以总数会比较多。一个比较好的判断你的系统是否需要增加这个值的办法

是在访问峰值的时候检查 open_tables 这个值,如果这个值和你设置的 table_cache

值一样,而且 opened_tables 的增长速度很快,那么你应该增加这个值,如果你有

空闲的内存。

下面列举3个在峰值情况下的例子:

情景分析1:

mysql> SHOW STATUS LIKE 'open%tables%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_tables | 98 |

| Opened_tables | 1513 |

+---------------+-------+

The table_cache is

set to 512, and the server has been running for a long time. If the server is

taking strain elsewhere, the table_cache setting could probably be reduced

safely.

在上面这个情形中,table_cache 设置的为 512,数据库已经运行了很长一段时间,

如果服务器在其他方面存在性能问题或者资源比较紧张,可以考虑适当的减小这个

值。

情景分析2:

mysql> SHOW STATUS LIKE 'open%tables%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_tables | 64 |

| Opened_tables | 517 |

+---------------+-------+

The table_cache is

set to 64, and the server has been running for a long time. Even though open_tables

is at its maximum, the number of open_tables is very low considering that the

server has been up for ages. There is probably not much benefit in upping the table_cache.

This example came from a development server.

上面的这个情形,table_cache 设置的是 64, 服务器也运行了好久,即使 open_tables

的值已经达到了最大值,但是 opend_tables 的值比较小,可以认为服务器的状况正常,

增加 table_cache 的值并不一定会有好的效果。

情景分析3:

mysql> SHOW STATUS LIKE 'open%tables%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_tables | 64 |

| Opened_tables | 13918 |

+---------------+-------+

The table_cache is

set to 64, and the server has been running for a short time. This time the table_cache

is clearly set too low. The open_tables is running at maximum, and the

number of opened_tables is already high. If you have the memory, up the table_cache.

上面的情形中, table_cache 设置为 64, 服务器运行的时间很短,open_tables 已经达到了

最大值,而 opened_tables 的值非常大,如果有足够的内存,应该继续增大 table_cache 的

值。

sort_buffer

本节提到的MySQL的配置变量:

sort_buffer

执行 myisamchk 和查询中有 sort

函数时使用的内存,在mysqld的配置小节 中设置为2M-8M比较合适.

The sort_buffer is

very useful for speeding up myisamchk operations (which is why it is set

much higher for that purpose in the default configuration files), but it can

also be useful everyday when performing large numbers of sorts. It defaults to

2M in the my-huge.cnf sample file, but I have successfully upped it to

9MB on a 3GB server running quite a few sorts.

这个值非常有助于提高执行 myisamchk 时的速度,所以在配置文件中关于 myisamchk 的

配置中这个的值设置的比较大。

这个值对于执行大量的 sort 排序操作时也非常有帮助,在my-huge.cnf配置文件中设置

为2M,但在我的3G内存的服务器上设置的是9M,排序的查询比较少。

read_rnd_buffer_size

The read_rnd_buffer_size

is used after a sort, when reading rows in sorted order. If you use many

queries with ORDER BY, upping this can improve performance. Remember

that, unlike key_buffer_size and table_cache, this buffer is allocated

for each thread. This variable was renamed from record_rnd_buffer in

MySQL 4.0.3. It defaults to the same size as the read_buffer_size, which

defaults to 128KB. A rule-of-thumb is to allocate 1KB for each 1MB of memory on

the server, for example 3MB on a machine with 3GB memory.

read_rnd_buffer_size 用在 sort 之后,以排序后的顺序读取记录时。如果有许多

查询都使用了 ORDER BY 函数,增大这个值可以提高性能。需要注意的是,这个值

不象 key_buffer_size 和 table_cache ,它的内存分配是对每个线程的,默认

会被设置的和 read_buffer_size 一样大小,为 128KB,经验值是每1M内存分配1KB,

比如3G内存的服务器可以分配3M。

tmp_table_size

This variable determines

the maximum size for a temporary table in memory. If the table becomes too

large, a MYISAM table is created on disk. Try to avoid temporary tables by

optimizing the queries where possible, but where this is not possible, try to

ensure temporary tables are always stored in memory. Watching the processlist

for queries with temporary tables that take too long to resolve can give you an

early warning that tmp_table_size needs to be upped. Be aware that

memory is also allocated per-thread. An example where upping this worked for

more was a server where I upped this from 32MB (the default) to 64MB with

immediate effect. The quicker resolution of queries resulted in less threads

being active at any one time, with all-round benefits for the server, and

available memory.

这个值决定内存中临时表的大小,如果表太大,那么MyISAM表将会创建在磁盘上。

尽量优化查询避免使用临时表,如果不行,确保临时表总是创建在内存中。

查询 processlist 如果查询使用临时表使用的时间比较长,说明有必要增加

tmp_table_size 的大小。也需要注意这个值是for 每个线程的。一个例子是我

在一个服务器上把这个值从32M增加到64M后立即就有效果。