您的位置:首页 > 数据库 > MySQL

通过实验分析索引对MySQL插入时性能的影响

2007-10-17 11:09 941 查看
虽说给表增加索引在查询的时候能大大加快查询速度,但是索引在修改的会降低数据库的性能(要检查、更新索引需要时间) 如果您发现实验过程有什么不当之处恳请指正 :)

实验结果:
没有索引 整型做Primary Key 整型做Index 字符串做Primary Key 字符串做Index
53 61 81 216 218
数据都是在插入100万的时候得出的,时间单位:秒
可以看出整型当成PK的时候,性能下降了13%,字符串的时候性能下降了4倍吧,没有必要的时候别用字符串做PK,整型做Index的时候性能下架了60%吧 (性能都是值插入数据的时候的性能)

当然如果你的查询次数远大于修改次数,这点性能的舍弃还是值得的!所以避免数据库中索引满天飞的情况吧
------------------------------------------------------------------------------

详细实验过程:(表的引擎都是 ENGINE=MyISAM )
先看表结构:
mysql> desc Test_Key;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
Int型的id在这里是主键

性能分析存储过程:
create PROCEDURE proc_test_performance(in count bigint)
BEGIN
DECLARE start_time BIGINT;
DECLARE end_time BIGINT;
DECLARE iter BIGINT;
select UNIX_TIMESTAMP() into start_time;
set iter = 0;
WHILE iter<count DO
insert into Test_Key(id,name) values(iter,CONCAT('test',iter));
set iter = iter+1;
end while;

select UNIX_TIMESTAMP() into end_time;

select (end_time-start_time),start_time, end_time;
select count(*) from Test_Key;
delete from Test_Key;
end;

执行结果:(单位是秒)3次执行分别为63,61,60
mysql> call proc_test_performance(1000000);
+-----------------------+------------+------------+
| (end_time-start_time) | start_time | end_time |
+-----------------------+------------+------------+
| 63 | 1190704959 | 1190705022 |
+-----------------------+------------+------------+
1 row in set (1 min 2.22 sec)

去掉Test_Key表中的Primary Key的限制,分别执行三次结果是:53,54,53秒。
mysql> desc Test_Key;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+

结论一:在这种情况下性能提升13%多一点点

-----------------------------------------------------------------------------
接下来再看看字符串做索引的时候对性能的影响:
mysql> desc Test_Key; (没有索引)
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
执行结果:
mysql> call proc_test_performance(1000000);
+-----------------------+------------+------------+
| (end_time-start_time) | start_time | end_time |
+-----------------------+------------+------------+
| 54 | 1190706332 | 1190706386 |
+-----------------------+------------+------------+
三次分别为:54,54,54秒

接着修改表的结构,给name加上primary key的约束
mysql> desc Test_Key;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | NO | PRI | | |
+-------+--------------+------+-----+---------+-------+
然后再插入3次时间分别为:216,215,217秒

-------------------------------------------------------------------------
接下来看看普通Index对性能的影响:
mysql> desc Test_Key;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | MUL | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
在int上建立Index,三次执行结果耗时分别为:81,82,81秒

mysql> desc Test_Key;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | YES | MUL | NULL | |
+-------+--------------+------+-----+---------+-------+
在Varchar上建立Index,三次执行结果耗时分别为:218,217,217秒

结论见上面

再来看一个有意思的结论:
修改插入值
drop procedure if EXISTS proc_test_performance;
create PROCEDURE proc_test_performance(in count bigint)
BEGIN
DECLARE start_time BIGINT;
DECLARE end_time BIGINT;
DECLARE iter BIGINT;
select UNIX_TIMESTAMP() into start_time;
set iter = 0;
WHILE iter<count DO
insert into Test_Key(id,name) values(iter,CONCAT(iter,'test'));//将数字(不同部分)放到前面去
set iter = iter+1;
end while;

select UNIX_TIMESTAMP() into end_time;

select (end_time-start_time),start_time, end_time;
select count(*) from Test_Key;
delete from Test_Key;
end;
三次插入的时间分别是:159,160,159秒,我想你应该明白为什么时间能减少这么多吧,呵呵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: