首页 > 数据库 >mysql cpu使用率高的常见原因 mysql cpu占用率过高

mysql cpu使用率高的常见原因 mysql cpu占用率过高

时间:2023-07-25 19:13:54浏览次数:45  
标签:show mydata cpu 索引 mysql t1 占用率 CPU

文章来自:https://blog.51cto.com/u_12192/6319295

简单的分为下面几个步骤来解决这个问题:1、mysql运行正常,也有可能是同步设置问题导致2、如果mysql运行正常,那就是php的一些sql语句导致问题发现,用root用户进入mysql管理 mysql -u root -p输入密码 mysql:show processlist; 语句,查找负荷最重的 SQL 语句,优化该SQL,比如适当建立某字段的索引。通过这个命令我看到原来是有人恶意刷搜索,因为dedecms搜索后面调用搜索最高的词,导致很多人用工具刷这个,而且是定时有间隔的,所以将这个php程序改名跳转都方法解决了。当然如果你的确实是sql语句用了大量的group by等语句,union联合查询等肯定会将mysql的占用率提高。所以就需要优化sql语句,网站尽量生成静态的,一般4W ip的静态网站,mysql占用率几乎为0的。

MYSQL CPU 占用 100% 的现象描述

早上帮朋友一台服务器解决了 Mysql cpu 占用 100% 的问题。稍整理了一下,将经验记录在这篇文章里朋友主机(Windows 2003 + IIS + PHP + MYSQL )近来 MySQL 服务进程 (mysqld-nt) CPU 占用率总为 100% 高居不下。此主机有10个左右的 database, 分别给十个网站调用。据朋友测试,导致 mysqld-nt 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占用再次降下来了。(2007.07.09 附注:关于 discuz 论坛的具体优化过程,我后来另写了一篇文章,详见:千万级记录的 Discuz! 论坛导致 MySQL CPU 100% 的 优化笔记 http://www.xiaohui.com/dev/server/20070701-discuz-mysql-cpu-100-optimize.htm)

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

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

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

根据 mysql 的开发文档:

索引 index 用于:

快速找出匹配一个WHERE子句的行 当执行联结(JOIN)时,从其他表检索行。 对特定的索引列找出MAX()或MIN()值 如果排序或分组在一个可用键的最左面前缀上进行(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有键值部分跟随DESC,键以倒序被读取。

在一些情况中,一个查询能被优化来检索值,不用咨询数据文件。如果对某些表的所有使用的列是数字型的并且构成某些键的最左面前缀,为了更快,值可以从索引树被检索出来。

假定你发出下列SELECT语句:

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

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

标签:show,mydata,cpu,索引,mysql,t1,占用率,CPU
From: https://www.cnblogs.com/haoxuanchen2014/p/17580728.html

相关文章

  • MySQL 事务机制
    事务机制:事务语法:--开始事务begin;--或starttransaction;--提交commit;--回滚rollback;--保存点savepoint;事务特性:默认事务:MySQL的事务默认自动提交:在自动提交的状态下每一条SQL就是一个事务会被直接执行手动开启事务后:则所有的SQL语句都在一个事......
  • MySQL 锁机制
    数据库锁:概念:锁是计算机协调多个进程或线程并发访问某一资源的机制(避免资源争抢)分类:按粒度表级锁:锁定整个表开销小加锁快不会出现死锁锁定粒度大发生锁冲突的概率最高并发度最低数据库引擎总是一次性同时获取所有需要的锁以及总是按相同的顺序获取表锁从而避免死......
  • MySQL 日志机制
    日志机制:错误日志:当数据库无法正常启动时第一个定位错误日志数据库速度慢时也可以定位错误日志得到建议(如增大缓存池增大redologbuffer等)查询日志:没啥用就是记录查询而已应该是为了对应binlog记录修改的日志慢查询日志:捕获查询慢的情况配置:可以设置每分钟最多有......
  • MySQL 数据库连接
    数据连接:连接:MySQL驱动:mysql-connector-Java-XXX.jar数据库连接的建立及关闭是及耗费系统资源的操作,在多层结构的应用环境中,这种资源的耗费对系统性能影响尤为明显。通过DriverManager获得数据库连接的方式,一个数据库连接对象对应一个物理数据库连接,每次操作都打开一个物......
  • MySQL 容灾备份
    容灾备份:数据备份:直接对数据库进行备份:#数据库备份语句#不指定表名的话默认就是整个数据库备份#备份文件可以指定绝对路径mysqldump-u[用户名]-p[库名][表名]...>[备份文件.sql]#多个数据库备份语句mysqldump-u[用户名]-p--databases[库名][库名]......
  • MySQL 索引
    索引分析:索引概述:定义:MySQL官方对索引的定义:索引(Index)是帮助MySQL高效获取数据的数据结构。结论:索引是数据结构结构:MySQL支持多种存储引擎而各种存储引擎对索引的支持也各不相同因此MySQL数据库支持多种索引类型如BTree索引、哈希索引、全文索引等等目前大部分数据库......
  • kettle连接数据库报错:Error connecting to database: (using class org.gjt.mm.mysql.
    kettle连接MySQL报错但已经把相应的包放到kettle的lib目录下时,仍然报连接不上的错误,那可能是MySQL时区的问题。解决如下:登入MySQL修改为东八区的命令:方法一:mysql>setglobalmax_allowed_packet=1024*1024;mysql>setglobaltime_zone='+8:00';方法二:修改my.ini文件,在[mysql......
  • Mysql开启慢查询日志
    查看mysql的慢查询日志是否开启showvariableslike'%query%';  可以看到slow_query_log的值是OFF,mysql默认是不启用慢查询日志的。这里还有个long_query_time,默认是10秒,也就是超过了10秒即为慢查询。log_queries_not_using_indexes,如果设置为ON,则会将所有没有使用索引的查......
  • mysql 中 myisam 与 innodb 的区别?
     1.事务支持>MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。>InnoDB:提供事务支持事务,外部键等高级数据库功能。具有事务(commit)、回滚(rollback)和崩溃修复能力(crashrecoverycapabilities)的事务安全(transaction-safe(......
  • 为什么 CPU 访问寄存器的速度比访问内存的速度快
    为什么CPU访问寄存器的速度比访问内存的速度快寄存器是位于CPU内部的高速存储器件,而内存则是位于CPU外部的存储器件。在计算机体系结构中,访问速度极大取决于数据存储设备与CPU之间的距离,当CPU需要从存储设备中读取数据时,必须通过一系列的总线、控制器等中间设备进行数......