经过之前对mysql的操做经验,先将mysql的配置问题排除了,查看msyql是否运行正常,经过查看mysql data目录里面的*.err文件(将扩展名改成.txt)记事本查看便可。若是过大不建议用记事本了,容易死掉,能够用editplus等工具
简单的分为下面几个步骤来解决这个问题:
一、mysql运行正常,也有多是同步设置问题致使
二、若是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性能 (
MySQL 性能优化的最佳20多条经验分享)
下面是脚本之家收集的文章,你们均可以参考下 MYSQL CPU 占用 100% 的现象描述 早上帮朋友一台服务器解决了 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占用再次降下来了。(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 值。 这是 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. 对 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上,优化器试图经过决定哪一个索引将找到更少的行并来找出更具限制性的索引而且使用该索引取行。 开发人员作 SQL 数据表设计的时候,必定要通盘考虑清楚。