mysql 优化
最近做的一个应用,功能要求非常简单,就是 key/value 形式的存储,简单的 INSERT/SELECT,没有任何复杂查询,唯一的问题是量非常大,如果目前投入使用,初期的单表 insert 频率约 20Hz(次/秒,我喜欢这个单位,让我想起国内交流电是 50Hz),但我估计以后会有 500Hz+ 的峰值。目前的工作成果,额定功率 200Hz(CPU 占用 10 – 20,load avg = 2),最大功率 500Hz(这时 load avg > 20,很明显,只能暂时挺挺,应该在出现这种负载前提前拆表了)
INSERT DELAYED INTO
从数据的插入开始说起。如果可以容忍结果几秒以后再生效的,可以用 INSERT DELAYED INTO,因为在我的这个结构中不需要对同一个
key 频繁的 INSERT/SELECT,因为 SELECT 我是用 Memcached 挡住了,除非 Memcached
挂了,或者数据实在老到过期了,才会去 SELECT。而且要注意,如果 PHP 不需要关心 MySQL 操作的返回结果,应该使用
unbuffered query,简单的说,在你提交 query 后,不用等待 MySQL 有返回信息就继续执行之后的 PHP
指令,具体用法是用 mysql_unbuffered_query 代替 mysql_query,如果用的 MySQLi 类,应该使用
mysqli->query($sQuery, MYSQLI_USE_RESULT);
如果 SHOW PROCESSLIST,可以看到用户名为 DELAYED 的进程,进程数量等于 INSERT DELAYED 的表的数量,因为表级锁的存在,每个表一条以上的 DELAYED 进程是没有意义的
关于这个功能的 my.cnf 配置有三条,我定为如下值
delayed_insert_limit = 1000delayed_insert_timeout = 300delayed_queue_size = 5000
连接
有 人说,如
摘自其他
1. 表字段分割。经常访问的表、行数量大的表,切记保持最少长度字段,不在select列表的数据,请做垂直分割。举例:文章表,不要将文章正文部分的内容存在文章信息表里,可以将这个字段独立存储到另一张表articleContent(articleID,articleContext)。因为这个字段长度大,影响查询时的行扫描。
2. 频繁更新的字段做表的垂直分割。在做更新操作时,一般会做行锁定,有的会设置成表锁定。那么在做query的时候,更新操作没完成前,所有查询都会排队等待。
3. 尽量做cache字段,减少表关联查询。
4. 对一些非重要、非实时性强的数据,做定时更新,而不是实时更新。
5. 索引。好的索引对查询的效果可以达成百上千倍,但前提是好的数据表结构设计。索引太多容易引起更新变慢。注意where和order by里的字段。关于索引,我会开专题讲解优化。
6. 定期重建索引。使用一定时间后,会有索引碎片的问题,这就如磁盘碎片整理。
7. 过滤慢查询,一般系统查询时间超过0.1s的都要检查。
8. 善用explain分析查询成本。进行了全表扫描的语句都要考虑优化,如几百内的小数据量表除外。
9. 配置参数优化。如临时表size、锁机制、数据库引擎类型。
相关链接:
http://www.dataguru.cn/thread-246126-1-1.html //很棒
2、解构技能,找出实现80%效果的那20%
3、不要一心二用
4、练习练习再练习!然后获得即时反馈
5、坚持,不要在低谷期放弃