分别创建两个表,t7和t8
create table t7(
id char(64) primary key,
ver int not null default 0,
str1 varchar(3000),
str2 varchar(3000),
str3 varchar(3000)
)engine =myisam default charset utf8;
create table t8(
id char(64) primary key,
ver int not null default 0,
str1 varchar(3000),
str2 varchar(3000),
str3 varchar(3000)
)engine =innodb default charset utf8;
分别向两个表中插入相同的1万条数据:
下面的语句,如果t7的表的主键为整型自增,则插入速度会更快
$conn = mysql_connect('localhost','root','');
mysql_query('use test',$conn);
mysql_query('set names utf8');
$str = str_repeat('m',3000);
for($i=1;$i<1;$i++){
$id = dechex($i);
$sql = sprintf("insert into t7 values ('%s','%d','%s','%s','%s')",$i,$i,$str,$str,$str);
mysql_query($sql,$conn);
}
下面的语句,如果t8的表的主键为整型自增,则插入速度会更快,但是总体的插入速度,相对上面的语句来说,还是相对较慢,因为聚簇索引的页分裂会花费很多时间
$conn = mysql_connect('localhost','root','');
mysql_query('use test',$conn);
mysql_query('set names utf8');
$str = str_repeat('m',3000);
for($i=1;$i<1;$i++){
$id = dechex($i);
$sql = sprintf("insert into t8 values ('%s','%d','%s','%s','%s')",$i,$i,$str,$str,$str);
mysql_query($sql,$conn);
}
给t7表,加入联合索引
alter table t7 add index idver(id,ver);
mysql> show profiles;
+----------+------------+-----------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------+
| 1 | 0.00031675 | set profiling = 1 |
| 2 | 0.00541950 | select id from t7 order by id |
| 3 | 0.00523250 | select id from t7 order by id |
| 4 | 0.00667300 | select id from t7 order by id,ver |
通过上面的分析我们可以发现,query_id为3和4的,两者的查询速度相差无几,我们可以看出,select id from t7 order by id
和select id from t7 order by id,ver,两种查询方法,实际效果差不多,这是因为,myisam的索引,最终都是指向物理地址,所以查询起来是没有多大差别的
给t8表,加上联合索引
alter table t8 add index idver(id,ver);
mysql> show profiles;
+----------+------------+-----------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------+
| 1 | 0.00031675 | set profiling = 1 |
| 2 | 0.00541950 | select id from t7 order by id |
| 3 | 0.00523250 | select id from t7 order by id |
| 4 | 0.00667300 | select id from t7 order by id,ver |
| 5 | 0.00009200 | clear query cache |
| 6 | 0.00010100 | resrt query cache |
| 7 | 0.00009500 | reset query cache |
| 8 | 0.16514825 | select id from t8 order by id |
| 9 | 0.00523850 | select id from t8 order by id,ver
通过上面的分析我们可以知道,8和9的查询速度,相差30倍,下面详细解释一下原因
通过上图我们可以知道,进行order by id的时候,数据会在很多数据块之间进行查询,因为数据中存在较大的str1,str2,str3,所以查询较慢,如果使用id,ver的联合索引查询,会直接查询到对应的id,这其中,order by id和order by id,ver两者都用到了索引覆盖(innodb的索引为聚簇索引)。
总结:
1.myisam的索引查询,最终都落地到了物理地址上,innodb的主键索引,下面都存储有该行的数据(聚簇索引),在查询的时候,如果查询的是主键,会存在索引覆盖的问题
2.如果将上面的str1,str2,str3三个字段删除,会将innodb的查询速度提升,因为innodb在不同的数据块之间的查询速度会提升