MySQL CPU占用过高怎么办?

最近发现php网站发布信息比较慢,而且同网站目录下的asp经常登录后立即就重新登录,立即考虑到服务器CPU资源占用问题,所以进服务器看到原来mysql占用过高25-60%左右,偶尔能跑到100%,所有导致上述问题的发生。MySQLCPU占用过高怎么办呢?接着忘下看。


通过以前对mysql的操作经验,先将mysql的配置问题排除了,查看msyql是否运行正常,通过查看mysqldata目录里面的*.err文件(将扩展名改为.txt)记事本查看即可。如果过大不建议用记事本了,容易死掉,可以用editplus等工具。




简单的分为下面几个步骤来解决这个问题:




1、mysql运行正常,也有可能是同步设置问题导致




2、如果mysql运行正常,那就是php的一些sql语句导致问题发现,用root用户进入mysql管理
mysql-uroot-p


输入密码
mysql:showprocesslist语句,查找负荷最重的SQL语句,优化该SQL,比如适当建立某字段的索引。




通过这个命令我看到原来是有人恶意刷搜索,因为dedecms搜索后面调用搜索最高的词,导致很多人用工具刷这个,而且是定时有间隔的,所以将这个php程序改名跳转都方法解决了。




当然如果你的确实是sql语句用了大量的groupby等语句,union联合查询等肯定会将mysql的占用率提高。所以就需要优化sql语句,网站尽量生成静态的,一般4Wip的静态网站,mysql占用率几乎为0的。所以这对于程序员的经验是个考虑。尽量提高mysql性能(MySQL性能优化的最佳20多条经验分享)




下面是豆芽收集的文章,大家都可以参考下


MYSQLCPU占用100%的现象描述


早上帮朋友一台服务器解决了Mysqlcpu占用100%的问题。稍整理了一下,将经验记录在这篇文章里


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


MYSQLCPU占用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>notepadc:\windows\my.ini
[mysqld]
tmp_table_size=200M


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


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


mysql>showprocesslist;


反复调用此命令,发现网站A的两个SQL语句经常在processlist中出现,其语法如下:


SELECTt1.pid,t2.userid,t3.count,t1.date
FROM_mydataASt1
LEFTJOIN_myuserASt3ONt1.userid=t3.userid
LEFTJOIN_mydata_bodyASt2ONt1.pid=t3.pid
ORDERBYt1.pid
LIMIT0,15
调用showcolumns检查这三个表的结构:


mysql>showcolumnsfrom_myuser;
mysql>showcolumnsfrom_mydata;
mysql>showcolumnsfrom_mydata_body;


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


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


mysql>ALTERTABLE`_mydata`ADDINDEX(`userid`)
建立此索引之后,CPU马上降到了80%左右。看到找到了问题所在,于是检查另一个反复出现在showprocesslist中的sql语句:


SELECTCOUNT(*)
FROM_mydataASt1,_mydata_keyASt2
WHEREt1.pid=t2.pidandt2.keywords='孔雀'


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


mysql>ALTERTABLE`_mydata_key`ADDINDEX(`keywords`)


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


再次调用showprosslist,网站A的sql调用就很少出现在结果列表中了。但发现此主机运行了几个Discuz的论坛程序,Discuz论坛的好几个表也存在着这个问题。于是顺手一并解决,cpu占用再次降下来了。(2007.07.09附注:关于discuz论坛的具体优化过程,我后来另写了一篇文章,详见:千万级记录的Discuz!论坛导致MySQLCPU100%的优化笔记 http://www.xiaohui.com/dev/server/20070701-discuz-mysql-cpu-100-optimize.htm)




解决MYSQLCPU占用100%的经验总结


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




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


根据mysql的开发文档:


索引index用于:


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


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


假定你发出下列SELECT语句:


mysql>SELECT*FROMtbl_nameWHEREcol1=val1ANDcol2=val2;


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


开发人员做SQL数据表设计的时候,一定要通盘考虑清楚。
来源:豆芽博客,地址: http://www.aichengxu.com/article/MySQL/866_10.html保留原文链接,是开源分享的开始.

你可能感兴趣的:(扩展名,服务器,sql语句,记事本,输入密码)