一、前言
最近在刚完成了pw版本的升级程序,拿了个拥有3万多用户的小站跑了下,结果一次503的time out错误,最后修修补补跑完之后发现用了将近1个小时。于是将运行最慢的几个模块分析了下SQL语句。记录下。
二、环境描述
数据库:mysql,原数据和目标数据同一个服务。
操作系统:本地的ubuntu12.10
描述:原PW87:用户数据量3.4W,2.1W帖子数据,7.9W回复数据,3.1W原私信数据,数据库使用的引擎是myisam,
新pw9的数据库采用innodb引擎
二、sql记录分析
监听到一条用户数据查询如下:
select * from pw_members order by uid limit 10000, 1000;
用explain分析得到如下:
myiasm引擎:
mysql> explain select * from pw_members order by uid limit 10000, 1000;
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
| 1 | SIMPLE | pw_members | ALL | NULL | NULL | NULL | NULL | 34730 | Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
1 row in set (0.00 sec)
innodb引擎:
mysql> explain select * from nw_user order by uid limit 10000, 1000;
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------+
| 1 | SIMPLE | nw_user | index | NULL | PRIMARY | 4 | NULL | 11000 | |
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------+
1 row in set (0.01 sec)
两表使用都对uid建立唯一索引,
换种写法:
SELECT uid FROM pw_members WHERE uid > 10000 ORDER BY uid LIMIT 1000;
myisam引擎:
mysql> explain SELECT uid FROM pw_members WHERE uid > 10000 ORDER BY uid LIMIT 1000;+----+-------------+------------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+------+-------+--------------------------+
| 1 | SIMPLE | pw_members | range | PRIMARY | PRIMARY | 4 | NULL | 26074 | Using where; Using index |
+----+-------------+------------+-------+---------------+---------+---------+------+-------+--------------------------+
innodb引擎:
mysql> explain select * from nw_user where uid > 10000 order by uid limit 10000, 1000;
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------------+
| 1 | SIMPLE | nw_user | range | PRIMARY | PRIMARY | 4 | NULL | 17461 | Using where |
+----+-------------+---------+-------+---------------+---------+---------+------+-------+-------------+
我的结论:
横向相比,对于第一种写法,innodb处理的方式会比myisam优雅点,而第二种写法则差不多。
纵向相比,则第二种写法处理起来无论在innodb或是myisam都比第一种写法优雅。
注:这次的数据量确实不大,所以得出这个结论也许有些站不住脚,等我遇到更大数据量的时候再来回头看看这个结论如何。
于是我将从myisam有主键的处理查询都改为第二种形式,从innodb处理的则根据情况处理。
三、
第一次处理这种数据转移,没有什么经验,也正在摸索阶段,希望各位大大么多多留言哈