`

Mysql 占用cpu资源高

阅读更多

朋友主机(Windows 2003 + IIS + PHP + MYSQL )近来 MySQL 服务进程 (mysqld-nt.exe) CPU 占用率总为 100% 高居不下。此主机有10个左右的 database, 分别给十个网站调用。据朋友测试,导致 mysqld-nt.exe cpu 占用奇高的是网站A,一旦在 IIS 中将此网站停止服务,CPU 占用就降下来了。一启用,则马上上升。

MYSQL CPU 占用 100% 的解决过程

今天早上仔细检查了一下。目前此网站的七日平均日 IP 为2000,PageView 为 3万左右。网站A 用的 database 目前有39个表,记录数 60.1万条,占空间 45MB。按这个数据,MySQL 不可能占用这么高的资源。

于是在服务器上运行命令,将 mysql 当前的环境变量输出到文件 output.txt:

d:\web\mysql> mysqld.exe –help >output.txt

发现 tmp_table_size 的值是默认的 32M,于是修改 My.ini, 将 tmp_table_size 赋值到 200M:

d:\web\mysql> notepad c:\windows\my.ini [mysqld] tmp_table_size=200M

然后重启 MySQL 服务。CPU 占用有轻微下降,以前的CPU 占用波形图是 100% 一根直线,现在则在 97%~100%之间起伏。这表明调整 tmp_table_size 参数对 MYSQL 性能提升有改善作用。但问题还没有完全解决。

于是进入 mysql 的 shell 命令行,调用 show processlist, 查看当前 mysql 使用频繁的 sql 语句:

mysql> show processlist;

反复调用此命令(每秒刷两次),发现网站 A 的两个 SQL 语句经常在 process list 中出现,其语法如下:

SELECT t1.pid, t2.userid, t3.count, t1.date FROM _mydata AS t1 LEFT JOIN _myuser AS t3 ON t1.userid=t3.userid LEFT JOIN _mydata_body AS t2 ON t1.pid=t3.pid ORDER BY t1.pid LIMIT 0,15

调用 show columns 检查这三个表的结构 :

mysql> show columns from _myuser; mysql> show columns from _mydata; mysql> show columns from _mydata_body;

终于发现了问题所在:_mydata 表,只根据 pid 建立了一个 primary key,但并没有为 userid 建立索引。而在这个 SQL 语句的第一个 LEFT JOIN ON 子句中:

LEFT JOIN _myuser AS t3 ON t1.userid=t3.userid

_mydata 的 userid 被参与了条件比较运算。于是我为给 _mydata 表根据字段 userid 建立了一个索引:

mysql> ALTER TABLE `_mydata` ADD INDEX ( `userid` )

建立此索引之后,CPU 马上降到了 80% 左右。看到找到了问题所在,于是检查另一个反复出现在 show processlist 中的 sql 语句:

SELECT COUNT(*) FROM _mydata AS t1, _mydata_key AS t2 WHERE t1.pid=t2.pid and t2.keywords = ‘孔雀’

经检查 _mydata_key 表的结构,发现它只为 pid 建了了 primary key, 没有为 keywords 建立 index。_mydata_key 目前有 33 万条记录,在没有索引的情况下对33万条记录进行文本检索匹配,不耗费大量的 cpu 时间才怪。看来就是针对这个表的检索出问题了。于是同样为 _mydata_key 表根据字段 keywords 加上索引:

mysql> ALTER TABLE `_mydata_key` ADD INDEX ( `keywords` )

建立此索引之后,CPU立刻降了下来,在 50%~70%之间震荡。

再次调用 show prosslist,网站A 的sql 调用就很少出现在结果列表中了。但发现此主机运行了几个 Discuz 的论坛程序, Discuz论坛的好几个表也存在着这个问题。于是顺手一并解决,cpu占用再次降下来了。

至此,问题解决。

解决 MYSQL CPU 占用 100% 的经验总结

1. 增加 tmp_table_size 值。mysql 的配置文件中,tmp_table_size 的默认大小是 32M。如果一张临时表超出该大小,MySQL产生一个 The table tbl_name is full 形式的错误,如果你做很多高级 GROUP BY 查询,增加 tmp_table_size 值。 这是 mysql 官方关于此选项的解释:

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.

2. 对 WHERE, JOIN, MAX(), MIN(), ORDER BY 等子句中的条件判断中用到的字段,应该根据其建立索引 INDEX。

索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。表越大,花费时间越多。如果表对于查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要考虑所有数据。如果一个表有1000行,这比顺序读取至少快100倍。所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B树中存储。

根据 mysql 的开发文档:

索引 index 用于:

o 快速找出匹配一个WHERE子句的行
o 当执行联结(JOIN)时,从其他表检索行。
o 对特定的索引列找出MAX()或MIN()值
o 如果排序或分组在一个可用键的最左面前缀上进行(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有键值部分跟随DESC,键以倒序被读取。
o 在一些情况中,一个查询能被优化来检索值,不用咨询数据文件。如果对某些表的所有使用的列是数字型的并且构成某些键的最左面前缀,为了更快,值可以从索引树被检索出来。
假定你发出下列SELECT语句:

mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

如果一个多列索引存在于col1和col2上,适当的行可以直接被取出。如果分开的单行列索引存在于col1和col2上,优化器试图通过决定哪个索引将找到更少的行并来找出更具限制性的索引并且使用该索引取行。

开发人员做 SQL 数据表设计的时候,一定要通盘考虑清楚

分享到:
评论

相关推荐

    mysql占用cpu过高 [mysqlcpu占用过高怎么解决] .docx

    MySQL占用CPU过高的解决方案 在这篇文章中,我们讨论了MySQL占用CPU过高的问题及其解决方案。该问题可能会导致服务器性能下降,影响用户体验。通过实践案例,我们将展示如何诊断和解决该问题。 一、问题描述 ...

    mysql占用率达到99%

    ### MySQL占用率达到99%:问题分析与解决方案 #### 一、问题背景 在服务器运维过程中,遇到MySQL数据库服务占用率高达99%的情况时,这通常意味着数据库服务正在面临严重的问题,可能导致整个系统的响应时间增加,...

    Mysql CPU占用高的问题解决方法小结

    ### MySQL CPU占用高的问题解决方法小结 #### 问题背景 最近发现php网站发布信息比较慢,而且同网站目录下的asp程序经常出现登录后立即重新登录的情况。经过调查,发现这是由于服务器资源占用过高所导致的。具体...

    查询那些语句占用CPU

    查询那些语句占用CPU

    使用LoadRunner监控MySQL在Apache下占用CPU资源情况的方法

    "使用LoadRunner监控MySQL在Apache下占用CPU资源情况的方法"这个主题旨在教你如何使用LoadRunner这一强大的性能测试工具来监控MySQL数据库和Apache HTTP服务器在运行时的CPU利用率。这有助于识别潜在的性能瓶颈,并...

    mysql占用CPU过高的解决办法(添加索引)

    MySQL数据库在运行过程中,如果CPU使用率过高,可能会影响整个系统的性能,甚至导致服务中断。这种情况通常是由于多种因素引起的,包括但不限于不优化的查询、无索引的查询、内存配置不当等。以下是一些解决MySQL ...

    MySQL服务器进程CPU占用100%的解决方法

    朋友主机(Windows 2003 + IIS + PHP + MYSQL )近来 ... MYSQL CPU 占用 100% 的解决过程 今天早上仔细检查了一下。目前此网站的七日平均日 IP 为2000,PageView 为 3万左右。网站A 用的 database 目前有39个表,记录数

    快速定位MSSQL占用CPU高的sql方法

    在使用Microsoft SQL Server(MSSQL)数据库时,有时会遇到CPU或内存占用过高的问题,这可能会影响系统的性能和稳定性。本篇文章将探讨如何快速定位导致MSSQL CPU占用高的SQL语句,以帮助优化数据库性能。 首先,...

    MySQL数据库CPU飙升及烂sql记录

    3. **内存配置不合理**:如果MySQL的缓冲池大小设置不当,可能导致频繁的磁盘I/O操作,消耗大量CPU资源。 4. **系统资源限制**:如操作系统级别的资源限制,比如打开文件的数量限制,也可能间接导致CPU使用率升高。...

    Mysql占用过高CPU时的优化手段(必看)

    当MySQL数据库占用过高CPU资源时,这通常意味着数据库性能出现了问题,可能会影响到系统的整体响应速度。以下是一些针对这种情况的优化策略: 1. **优化SQL语句**:首先要找到CPU消耗最大的SQL语句,可以使用`SHOW ...

    解决 MySQL 服务器进程 CPU 占用 100%25的技术笔记.doc

    - 初步判断:根据服务器及数据库的配置和负载情况,理论上 MySQL 不应该占用如此高的资源。 2. **调整临时表大小参数(tmp_table_size)** - 使用 `mysqld.exe --help` 命令获取 MySQL 的当前环境变量,并输出到...

    使用MySQL Slow Log来解决MySQL CPU占用高的问题

    当MySQL在处理查询时消耗过多CPU资源,可能导致整个系统负载增加,从而影响服务的响应速度和整体效率。通过分析Slow Log,我们可以找出执行时间过长的SQL语句,这些往往是性能瓶颈的关键所在。 首先,启用MySQL ...

    关于Mysql数据库导致CPU很高的问题解决.docx

    这些错误可能会导致 MySQL 数据库的连接数增加,从而引起 CPU 占用率高的问题。 解决方法: 1. 确保关闭数据库连接,以避免连接数的增加。 2. 正确地处理错误信息,以避免错误的累积。 3. 使用 PHP 代码的 debug ...

    MySQL占用内存较大与CPU过高测试与解决办法

    MySQL数据库在运行过程中可能会出现内存占用过大和CPU使用率过高的情况,这通常是由于配置不当或者数据库工作负载较重导致的。以下是一些关键的配置参数及其解释,可以帮助你优化MySQL以降低内存消耗和CPU使用: 1....

    php-fpm 占用CPU过高,100%的解决方法

    ### php-fpm 占用CPU过高,100%的解决方法 #### 一、问题背景与概述 在日常运维工作中,我们可能会遇到服务器资源占用过高的情况,尤其是在使用PHP和Nginx构建Web应用时。本文将详细介绍当php-fpm进程占用CPU达到...

    【MySQL面试第二弹】MySQL 服务占用cpu 100%,如何排查问题?

    1. **内存消耗过大**:当MySQL数据库内存使用过高,可能导致频繁的Full GC,从而引起CPU资源的大量消耗。可以通过`jstat -gcutil`命令监控GC情况,观察Full GC的频率和趋势。如果发现内存溢出,可以使用`jmap -heap`...

Global site tag (gtag.js) - Google Analytics