데이터 베이스 MySQL 튜토리얼 [转] mysql性能优化议案

[转] mysql性能优化议案

Jun 07, 2016 pm 04:25 PM
mysql 최적화 성능 계획

[转] mysql性能优化方案 网上有不少mysql 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果,因此简单地根据某个给出方案来配置mysql是

[转] mysql性能优化方案

网上有不少mysql 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果,因此简单地根据某个给出方案来配置mysql是行不通的,最好能使用status信息对mysql进行具体的优化,网上找了一篇文章,分页分得乱七八糟的,只能转到博客。

?

在MySQL里,我们一般使用SHOW STATUS查询服务器状态,语法一般来说如下:

SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]

查询配置的变量可以用

SHOW variables [LIKE 'pattern' | WHERE expr] 如:show variables variable_name in('a', 'b');
로그인 후 복사

?可以列出mysql服务器运行各种状态值,另外,查询mysql服务器配置信息语句:

mysql> show global status;
mysql> show variables;
로그인 후 복사

?

[1] 慢查询

mysql> show variables like ‘%slow%‘;
+------------------+-------+
| variable_name     | value |
+------------------+-------+
| log_slow_queries | on     |
| slow_launch_time | 2      |
+------------------+-------+

mysql> show global status like ‘%slow%‘;
+---------------------+-------+
| variable_name        | value |
+---------------------+-------+
| slow_launch_threads | 0      |
| slow_queries         | 4148 |
+---------------------+-------+ 
로그인 후 복사

?配置中打开了记录慢查询,执行时间超过2秒的即为慢查询,系统显示有4148个慢查询,你可以分析慢查询日志,找出有问题的sql语句,慢查询时间不宜设置过长,否则意义不大,最好在5秒以内,如果你需要微秒级别的慢查询,可以考虑给mysql打补丁:http://www.percona.com/docs/wiki/release:start,记得找对应的版本。

打开慢查询日志可能会对系统性能有一点点影响,如果你的mysql是主-从结构,可以考虑打开其中一台从服务器的慢查询日志,这样既可以监控慢查询,对系统性能影响又小。

?

[2] 连接数

经常会遇见”mysql: error 1040: too many connections”的情况,一种是访问量确实很高,mysql服务器抗不住,这个时候就要考虑增加从服务器分散读压力,另外一种情况是mysql配置文件中max_connections值过小:

mysql> show variables like ‘max_connections‘;
+-----------------+-------+
| variable_name    | value |
+-----------------+-------+
| max_connections | 256   |
+-----------------+-------+
로그인 후 복사

?这台mysql服务器最大连接数是256,然后查询一下服务器响应的最大连接数:

mysql> show global status like ‘max_used_connections‘;

mysql服务器过去的最大连接数是245,没有达到服务器连接数上限256,应该没有出现1040错误,比较理想的设置是

max_used_connections / max_connections * 100% ≈ 85%

最大连接数占上限连接数的85%左右,如果发现比例在10%以下,mysql服务器连接数上限设置的过高了。

?

[3] key_buffer_size

key_buffer_size是对myisam表性能影响最大的一个参数,下面一台以myisam为主要存储引擎服务器的配置:

mysql> show variables like ‘key_buffer_size‘;+-----------------+------------+
| variable_name    | value       |
+-----------------+------------+
| key_buffer_size | 536870912 |
+-----------------+------------+
分配了512mb内存给key_buffer_size,我们再看一下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%

//比如上面的数据,key_cache_miss_rate为0.0244%,4000个索引读取请求才有一个直接读硬盘,已经很bt了,key_cache_miss_rate在0.1%以下都很好(每1000个请求有一个直接读硬盘),如果key_cache_miss_rate在0.01%以下的话,key_buffer_size分配的过多,可以适当减少。

mysql服务器还提供了key_blocks_*参数:
mysql> show global status like ‘key_blocks_u%‘;
+------------------------+-------------+
| variable_name           | value        |
+------------------------+-------------+
| key_blocks_unused       | 0            |
| key_blocks_used         | 413543       |
+------------------------+-------------+
//key_blocks_unused表示未使用的缓存簇(blocks)数,key_blocks_used表示曾经用到的最大的blocks数,比如这台服务器,所有的缓存都用到了,要么增加key_buffer_size,要么就是过渡索引了,把缓存占满了。比较理想的设置:

//key_blocks_used / (key_blocks_unused + key_blocks_used) * 100% ≈ 80%
로그인 후 복사

?

[4] 临时表

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增加,如果是在磁盘上创建临时表,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%,应该相当好了。我们再看一下mysql服务器对临时表的配置:

mysql> show variables where variable_name in (‘tmp_table_size‘, ‘max_heap_table_size‘);
+---------------------+-----------+
| variable_name        | value      |
+---------------------+-----------+
| max_heap_table_size | 268435456 |
| tmp_table_size       | 536870912 |
+---------------------+-----------+
//只有256mb以下的临时表才能全部放内存,超过的就会用到硬盘临时表。
로그인 후 복사

?[5] open table情况

mysql> show global status like ‘open%tables%‘;
+---------------+-------+
| variable_name | value |
+---------------+-------+
| open_tables    | 919    |
| opened_tables | 1951  |
+---------------+-------+
로그인 후 복사

?open_tables表示打开表的数量,opened_tables表示打开过的表数量,如果opened_tables数量过大,说明配置中table_cache(5.1.3之后这个值叫做table_open_cache)值可能太小,我们查询一下服务器table_cache值:

mysql> show variables like ‘table_cache‘;
+---------------+-------+
| variable_name | value |
+---------------+-------+
| table_cache    | 2048  |
+---------------+-------+
//比较合适的值为:
//open_tables / opened_tables * 100% >= 85%
//open_tables / table_cache * 100% <= 95%
로그인 후 복사

?

[6] 进程使用情况

mysql> show global status like ‘thread%‘;
+-------------------+-------+
| variable_name      | value |
+-------------------+-------+
| threads_cached     | 46     |
| threads_connected | 2      |
| threads_created    | 570    |
| threads_running    | 1      |
+-------------------+-------+
로그인 후 복사

?如果我们在mysql服务器配置文件中设置了thread_cache_size,当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)。threads_created表示创建过的线程数,如果发现threads_created值过大的话,表明mysql服务器一直在创建线程,这也是比较耗资源,可以适当增加配置文件中thread_cache_size值,查询服务器thread_cache_size配置:

mysql> show variables like ‘thread_cache_size‘;
+-------------------+-------+
| variable_name      | value |
+-------------------+-------+
| thread_cache_size | 64     |
+-------------------+-------+
//示例中的服务器还是挺健康的。
로그인 후 복사

?[7] 查询缓存(query cache)

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查询缓存变量解释:

qcache_free_blocks:缓存中相邻内存块的个数。数目大说明可能有碎片。flush query cache会对缓存中的碎片进行整理,从而得到一个空闲块。

qcache_free_memory:缓存中的空闲内存。

qcache_hits:每次查询在缓存中命中时就增大

qcache_inserts:每次插入一个查询时就增大。命中次数除以插入次数就是不中比率。

qcache_lowmem_prunes:缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;如果这个数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocks和free_memory可以告诉您属于哪种情况)

qcache_not_cached:不适合进行缓存的查询的数量,通常是由于这些查询不是 select 语句或者用了now()之类的函数。

qcache_queries_in_cache:当前缓存的查询(和响应)的数量。

qcache_total_blocks:缓存中块的数量。

?

我们再查询一下服务器关于query_cache的配置:

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        |
+------------------------------+-----------+
로그인 후 복사

?各字段的解释:

query_cache_limit:超过此大小的查询将不缓存

query_cache_min_res_unit:缓存块的最小大小

query_cache_size:查询缓存大小

query_cache_type:缓存类型,决定缓存什么样的查询,示例中表示不缓存 select sql_no_cache 查询

query_cache_wlock_invalidate:当有其他客户端正在对myisam表进行写操作时,如果查询在query cache中,是否返回cache结果还是等写操作完成再读表获取结果。

query_cache_min_res_unit的配置是一柄”双刃剑”,默认是4kb,设置值大对大数据查询有好处,但如果你的查询都是小数据查询,就容易造成内存碎片和浪费。

?

查询缓存碎片率 = 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%,命中率很差,可能写操作比较频繁吧,而且可能有些碎片。

?

[8] 排序使用情况

mysql> show global status like ‘sort%‘;
+-------------------+------------+
| variable_name      | value       |
+-------------------+------------+
| sort_merge_passes | 29          |
| sort_range         | 37432840    |
| sort_rows          | 9178691532 |
| sort_scan          | 1860569     |
+-------------------+------------+
로그인 후 복사

?sort_merge_passes 包括两步。mysql 首先会尝试在内存中做排序,使用的内存大小由系统变量 sort_buffer_size 决定,如果它的大小不够把所有的记录都读到内存中,mysql 就会把每次在内存中排序的结果存到临时文件中,等 mysql 找到所有记录之后,再把临时文件中的记录做一次排序。这再次排序就会增加 sort_merge_passes。实际上,mysql 会用另一个临时文件来存再次排序的结果,所以通常会看到 sort_merge_passes 增加的数值是建临时文件数的两倍。因为用到了临时文件,所以速度可能会比较慢,增加 sort_buffer_size 会减少 sort_merge_passes 和 创建临时文件的次数。但盲目的增加 sort_buffer_size 并不一定能提高速度,见 how fast can you sort data with mysql?(引自http://qroom.blogspot.com/2007/09/mysql-select-sort.html,貌似被墙)

?

另外,增加read_rnd_buffer_size(3.2.3是record_rnd_buffer_size)的值对排序的操作也有一点的好处,参见:http://www.mysqlperformanceblog.com/2007/07/24/what-exactly-is-read_rnd_buffer_size/

?

[9] 文件打开数

mysql> show global status like ‘open_files‘;
+---------------+-------+
| variable_name | value |
+---------------+-------+
| open_files     | 1410  |
+---------------+-------+

mysql> show variables like ‘open_files_limit‘;
+------------------+-------+
| variable_name     | value |
+------------------+-------+
| open_files_limit | 4590  |
+------------------+-------+
//比较合适的设置:open_files / open_files_limit * 100% <= 75%
로그인 후 복사

?

[10] 表锁情况

mysql> show global status like ‘table_locks%‘;
+-----------------------+-----------+
| variable_name          | value      |
+-----------------------+-----------+
| table_locks_immediate | 490206328 |
| table_locks_waited     | 2084912    |
+-----------------------+-----------+
table_locks_immediate表示立即释放表锁数,table_locks_waited表示需要等待的表锁数,如果table_locks_immediate / table_locks_waited > 5000,最好采用innodb引擎,因为innodb是行锁而myisam是表锁,对于高并发写入的应用innodb效果会好些。示例中的服务器table_locks_immediate / table_locks_waited = 235,myisam就足够了。
로그인 후 복사

?

[11] 表扫描情况

mysql> show global status like ‘handler_read%‘;
+-----------------------+-------------+
| variable_name          | value        |
+-----------------------+-------------+
| handler_read_first     | 5803750      |
| handler_read_key       | 6049319850  |
| handler_read_next      | 94440908210 |
| handler_read_prev      | 34822001724 |
| handler_read_rnd       | 405482605    |
| handler_read_rnd_next | 18912877839 |
+-----------------------+-------------+
各字段解释参见http://hi.baidu.com/thinkinginlamp/blog/item/31690cd7c4bc5cdaa144df9c.html,调出服务器完成的查询请求次数:

mysql> show global status like ‘com_select‘;
+---------------+-----------+
| variable_name | value      |
+---------------+-----------+
| com_select     | 222693559 |
+---------------+-----------+
로그인 후 복사

?

计算表扫描率:

?

表扫描率 = handler_read_rnd_next / com_select

?

如果表扫描率超过4000,说明进行了太多表扫描,很有可能索引没有建好,增加read_buffer_size值会有一些好处,但最好不要超过8mb。

?

后记:

?

文中提到一些数字都是参考值,了解基本原理就可以,除了mysql提供的各种status值外,操作系统的一些性能指标也很重要,比如常用的top,iostat等,尤其是iostat,现在的系统瓶颈一般都在磁盘io上,关于iostat的使用,可以参考:http://www.php-oa.com/2009/02/03/iostat.html

?

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

MySQL : 초보자를위한 데이터 관리의 용이성 MySQL : 초보자를위한 데이터 관리의 용이성 Apr 09, 2025 am 12:07 AM

MySQL은 설치가 간단하고 강력하며 데이터를 쉽게 관리하기 쉽기 때문에 초보자에게 적합합니다. 1. 다양한 운영 체제에 적합한 간단한 설치 및 구성. 2. 데이터베이스 및 테이블 작성, 삽입, 쿼리, 업데이트 및 삭제와 같은 기본 작업을 지원합니다. 3. 조인 작업 및 하위 쿼리와 같은 고급 기능을 제공합니다. 4. 인덱싱, 쿼리 최적화 및 테이블 파티셔닝을 통해 성능을 향상시킬 수 있습니다. 5. 데이터 보안 및 일관성을 보장하기위한 지원 백업, 복구 및 보안 조치.

Navicat에서 데이터베이스 비밀번호를 검색 할 수 있습니까? Navicat에서 데이터베이스 비밀번호를 검색 할 수 있습니까? Apr 08, 2025 pm 09:51 PM

Navicat 자체는 데이터베이스 비밀번호를 저장하지 않으며 암호화 된 암호 만 검색 할 수 있습니다. 솔루션 : 1. 비밀번호 관리자를 확인하십시오. 2. Navicat의 "비밀번호 기억"기능을 확인하십시오. 3. 데이터베이스 비밀번호를 재설정합니다. 4. 데이터베이스 관리자에게 문의하십시오.

Navicat Premium을 만드는 방법 Navicat Premium을 만드는 방법 Apr 09, 2025 am 07:09 AM

Navicat Premium을 사용하여 데이터베이스 생성 : 데이터베이스 서버에 연결하고 연결 매개 변수를 입력하십시오. 서버를 마우스 오른쪽 버튼으로 클릭하고 데이터베이스 생성을 선택하십시오. 새 데이터베이스의 이름과 지정된 문자 세트 및 Collation의 이름을 입력하십시오. 새 데이터베이스에 연결하고 객체 브라우저에서 테이블을 만듭니다. 테이블을 마우스 오른쪽 버튼으로 클릭하고 데이터 삽입을 선택하여 데이터를 삽입하십시오.

MySQL에서 테이블을 복사하는 방법 MySQL에서 테이블을 복사하는 방법 Apr 08, 2025 pm 07:24 PM

MySQL에서 테이블을 복사하려면 새 테이블을 만들고, 데이터를 삽입하고, 외래 키 설정, 인덱스 복사, 트리거, 저장된 절차 및 기능이 필요합니다. 특정 단계에는 다음이 포함됩니다 : 동일한 구조를 가진 새 테이블 작성. 원래 테이블의 데이터를 새 테이블에 삽입하십시오. 동일한 외래 키 제약 조건을 설정하십시오 (원래 테이블에 하나가있는 경우). 동일한 색인을 만듭니다. 동일한 트리거를 만듭니다 (원래 테이블에 하나가있는 경우). 동일한 저장된 절차 또는 기능을 만듭니다 (원래 테이블이 사용되는 경우).

MariaDB 용 Navicat에서 데이터베이스 비밀번호를 보는 방법은 무엇입니까? MariaDB 용 Navicat에서 데이터베이스 비밀번호를 보는 방법은 무엇입니까? Apr 08, 2025 pm 09:18 PM

MariaDB 용 Navicat은 암호가 암호화 된 양식으로 저장되므로 데이터베이스 비밀번호를 직접 볼 수 없습니다. 데이터베이스 보안을 보장하려면 비밀번호를 재설정하는 세 가지 방법이 있습니다. Navicat을 통해 비밀번호를 재설정하고 복잡한 비밀번호를 설정하십시오. 구성 파일을 봅니다 (권장되지 않음, 위험이 높음). 시스템 명령 줄 도구를 사용하십시오 (권장되지 않으면 명령 줄 도구에 능숙해야 함).

MySQL을 보는 방법 MySQL을 보는 방법 Apr 08, 2025 pm 07:21 PM

다음 명령으로 MySQL 데이터베이스를보십시오. 서버에 연결하십시오. mysql -u username -p password run show database; 기존의 모든 데이터베이스를 가져 오려는 명령 데이터베이스 선택 : 데이터베이스 이름 사용; 보기 테이블 : 테이블 표시; 테이블 구조보기 : 테이블 이름을 설명합니다. 데이터보기 : 테이블 이름에서 *를 선택하십시오.

MySQL을 복사하여 붙여 넣는 방법 MySQL을 복사하여 붙여 넣는 방법 Apr 08, 2025 pm 07:18 PM

MySQL에서 복사 및 붙여 넣기 단계는 다음 단계가 포함됩니다. 데이터를 선택하고 CTRL C (Windows) 또는 CMD C (MAC)로 복사; 대상 위치를 마우스 오른쪽 버튼으로 클릭하고 페이스트를 선택하거나 Ctrl V (Windows) 또는 CMD V (Mac)를 사용하십시오. 복사 된 데이터는 대상 위치에 삽입되거나 기존 데이터를 교체합니다 (데이터가 이미 대상 위치에 존재하는지 여부에 따라).

Navicat에서 SQL을 실행하는 방법 Navicat에서 SQL을 실행하는 방법 Apr 08, 2025 pm 11:42 PM

Navicat에서 SQL을 수행하는 단계 : 데이터베이스에 연결하십시오. SQL 편집기 창을 만듭니다. SQL 쿼리 또는 스크립트를 작성하십시오. 실행 버튼을 클릭하여 쿼리 또는 스크립트를 실행하십시오. 결과를 봅니다 (쿼리가 실행 된 경우).

See all articles