`
lgcpeter
  • 浏览: 90168 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

mysql占用资源过多(转)

阅读更多

早上帮朋友一台服务器解决了 Mysql cpu 占用 100% 的问题,稍整理如下,希望对各位有所帮助。

朋友主机(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 句柄数占用过多的解决方法

    MySQL句柄数占用过多的情况通常是由于数据库操作频繁或者配置不当导致的,这会影响系统的整体性能,甚至可能导致系统响应变慢。解决这个问题的关键在于理解和优化MySQL的相关配置,特别是针对InnoDB存储引擎的部分。...

    多线程下mysql连接数过多解决demo

    在多线程环境中,MySQL连接数过多的问题是一个常见的性能瓶颈,尤其在高并发的应用场景下。这通常是由于每个线程创建一个独立的数据库连接导致的,当并发线程数量增加时,连接池中的连接数量也随之增加,如果超过...

    解决mysql数据库连接过多的错误

    然而,增大连接数并不总是最佳解决方案,因为每个连接都会占用一定的系统资源。因此,现代应用程序通常会采用数据库连接池技术,它能有效地管理数据库连接,避免频繁创建和销毁连接,减少资源消耗。即使使用了连接池...

    MySql减少内存占用的方法详解

    然而,如果不进行适当的配置,MySQL可能会占用过多的系统内存,导致其他应用或系统资源紧张。针对这种情况,本文将深入探讨如何有效地减少MySQL的内存占用。 首先,了解MySQL内存使用的几个关键组件是必要的。其中...

    MySQL Sleep连接过多问题解决方法

    1. **客户端程序未正确关闭连接**:如果在程序退出前没有调用`mysql_close()`函数,数据库连接将不会被关闭,从而持续占用资源。这可能是编程时的疏忽,也可能是使用的数据库连接池没有自动管理连接。 2. **超时...

    查找最消耗资源的sql

    - **资源限制**:设置查询资源限制,如最大内存使用量,防止单一查询占用过多资源。 - **定期维护**:定期清理无用的数据,重建索引,优化统计信息。 5. **SQL Profiling** - 分析执行计划,检查是否存在不合理...

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

    1. **优化SQL语句**:首先要找到CPU消耗最大的SQL语句,可以使用`SHOW PROCESSLIST`命令来查看正在执行的进程,找出执行时间长且占用资源多的SQL。对这些语句进行优化,例如添加合适的索引,避免全表扫描。 2. **...

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

    本文将深入探讨MySQL占用CPU过高的原因,并提供一个通过添加索引来解决问题的具体案例。 首先,当MySQL服务器CPU使用率持续较高时,首要任务是定位问题的根源。可以通过`SHOW PROCESSLIST`命令来查看当前正在执行的...

    windows mysql-8.0.32下载安装详细教程

    下载完成后,解压缩文件到您选择的位置,建议避免将文件放在C盘以防止占用过多系统资源。 2. **配置文件my.ini**: 在解压后的文件夹中创建一个名为`data`的文件夹,用于存放数据库文件。同时,创建一个名为`my.ini`...

    MySQL数据库巡检手册 MySQL DBA必备

    - 需要注意服务器是否运行了其他服务,导致系统资源被占用过多,影响MySQL数据库的性能。 5. 其他常规检查项: - 通过查看数据库的错误日志来确定是否有异常错误发生。 - 检查数据库的备份策略是否得到执行,并...

    mySQL占用虚拟内存达8百多兆问题解决思路

    当发现MySQL占用虚拟内存高达800多兆时,这可能会影响系统的性能,甚至导致其他应用程序因内存不足而运行缓慢。以下是一些解决问题的思路和优化配置的方法。 首先,我们需要了解MySQL中的几个关键参数对内存使用的...

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

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

    mysql-5.5.60-64位Windows安装包与安装教程

    确保选择合适的安装位置,不要安装在系统盘上以避免占用过多空间。 4. **创建root用户**:安装过程中,系统会提示创建一个管理员级别的root用户。输入强密码并记住,此账户将用于管理数据库和执行所有权限操作。 5...

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

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

    MySQL监视器监视数据库动态

    此外,监视器还可以记录慢查询,帮助我们识别那些执行时间过长、消耗资源过多的SQL语句,从而进行进一步的优化。 其次,内存管理是数据库性能的关键因素。MySQL监视器能够显示缓冲池的使用情况,如InnoDB Buffer ...

    Windows系统如何安装Mysql_5.7.36-winx64免安装版

    在Windows系统上安装MySQL_5.7.36-winx64免安装版是一个非常实用的方法,特别是对于那些不希望占用过多系统资源或者频繁迁移数据库服务的用户。这个过程涉及几个关键步骤,包括解压文件、配置环境变量、创建数据目录...

    查看Mysql运行状态

    3. **使用 SHOW OPEN TABLES 命令**:用于显示当前打开的所有表的信息,有助于判断是否有表被长时间锁定或占用资源过多的情况。 ```sql SHOW OPEN TABLES; ``` 4. **使用 mysqladmin 工具**:这是一个强大的...

Global site tag (gtag.js) - Google Analytics