建立测试数据表
CREATE TABLE `milliontest` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT ,
`name` CHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
`content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`time` INT( 11 ) NOT NULL DEFAULT '0',
`lastmodify` DATETIME NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = Myisam
用上面的语句创建一个测试用的表。表中包含5个字段,自增主键ID,标题名字name,内容content以及创建时间time与最后编辑时间lastmodify,其中time字段用时间戳而编辑时间为年月日格式。由于目前表内没有任何数据,接下来当然是往表里灌数据,灌上100W(唬人用)。
我写了一个php脚本来完成这个任务。代码如下,各位大大不要耻笑:
set_time_limit(0);
$conn = mysql_connect('localhost', 'root', '');
mysql_select_db('test');
$titles = array(
'任天堂3DS发售,2000RMB兲朝币',
'明猪昨天买了飞行俱乐部', '前天第一次玩街霸网战虐人了!'
);
$contents = array(
'据美国国家地理网站报道,美国“国家地理新闻”网站刊登了过去一周的精彩太空图片。
这些图片集中展现了极光、土卫一“米玛斯”、Abell 383星系团以及好似绿龙般的SH
2-235星云等壮观景象',
'由于北极气候变暖,大量永冻土带融化,流入海洋。新研究发现,北极部分地区的永
久冻结带每年遭侵蚀的程度最多达到100英尺(约合30米)。');
$max = 1000000;
mysql_query("set names utf8");
for($i = 0; $i < $max; $i++) {
$tn = array_rand($titles);
$cn = array_rand($contents);
$time = time();
$lastmodify = date('Y-m-d H:i:s');
$res = mysql_query('insert into milliontest set name="'.$titles[$tn].'",
content="'.$contents[$cn].'", time="'.$time.'", lastmodify="'.$lastmodify.'"');
file_put_contents('million_log.txt', $i);
}
花了20多分钟时间数据库里终于有100w的数据了,泪流满面。那么下面就打开mysql终端开始华丽的测试一下。
select * from milliontest where time=1303812283;
/*略去搜索结果*/
146 rows in set (8.16 sec)
一条简单的查询就花了小小的8秒钟时间哦,要是100个人同时访问某个页面而同时运行了这条简单的语句,结果会怎么样咩?
这里我又做了另一个测试,注意跟上面那条sql语句的区别:
select * from milliontest where time='1303812283';
/*略去搜索结果*/
146 rows in set (55.98 sec)
看到这查询时间,我自己都扭曲了,我只是查询一个想要的结果而已,却花56秒近1分钟的时间来等待查询。所以小提一下sql语句中各位注意一下引号吧。
又做了几组测试,时间多在8秒波动,有空各位自己慢慢测~
现在给time字段加一个索引
mysql> alter table milliontest add index (`time`);
Query OK, 1000000 rows affected (33.88 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
建完索引,继续做一下上面的测试吧,嘻嘻。
mysql> select * from milliontest where time='1303812291';
615 rows in set (0.05 sec)
加了索引后这次花了0.05秒,相对之前的数据,速度提升相当多吧哈哈哈。不过这么简单的查询却花了0.05秒,对于并发量大的时候估计也不乐观咩,咱们试试去掉引号?
mysql> select * from milliontest where time=1303812283;
146 rows in set (0.00 sec)
爽吧!花费时间0.00!
体会到了索引带来的好处了吧,不过话说我突然想起来,跑去看了一下这张表占的磁盘容量,泪流满面我没找到wamp这个软件吧索引文件丢到哪去了,总之之前我在自己ubuntu下做的测试好像加表数据占了磁盘800M还是多少,忘了
分页的SQL优化(limit优化)
之前在网上看的时候看到很多关于limit优化的文章,不小心看到一篇分页优化,哎哟看完那篇文章之后,我突然恍然大悟,附我跟主管的某段对话:
主管:好像现在后台有点慢?
我:估计是数据正在批量入库的缘故,不快。
但事后我重新测试了下后台,速度还是NN慢。刚好想到某篇分页测试的文章,提到:
select id,name from milliontest limit 0,20;的速度与select id,name from milliontest limit N,20;
不一样,查询结果的速度取决于N,也就是N越大,速度越慢。
嘴巴说没什么用,还是看事实。
mysql> select id,name from milliontest limit 0,20;
20 rows in set (0.00 sec)
而
mysql> select id,name from milliontest limit 100000,20;
20 rows in set (0.25 sec)
再看
mysql> select id,name from milliontest limit 500000,20;
20 rows in set (1.05 sec)
明显查询时间有了小增长吧。后面的时间更恐怖哟。所以很多论坛之类的,数据太久的就不显示出来了,或者加缓存,那是其他的技术咯。 阅读全文 ……