首页 > 代码库 > 一次innodb自增主键重要性案例
一次innodb自增主键重要性案例
一次给市场部统计报表数据的案例:
其中有个临时实体表的表创建的时候使用的create table table_name select xxx from ,所以并未创建主键
创建完成后,我还给其中字段加了索引,索引列基数为1,所以索引选择性是非常好的!
表结构如下:
mysql> desc tbl_userlogin_info_tmp2;
+--------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| userid | int(11) | YES | MUL | NULL | |
| p | bigint(21) | NO | | 0 | |
+--------+------------+------+-----+---------+-------+
字段userid上是有索引的,并且索引列基数为1
然后看执行计划:
mysql> desc select f.schoolid,d.schoolname,count(*) as numbers,f.manager
-> from cw_relations.cw_groupclassmember as a
-> inner join cw_relations.cw_groupclass as b on a.gcid=b.id
-> inner join cw_relations.cw_class as c on b.id=c.cid
-> inner join cw_relations.cw_school as d on c.schoolid=d.schoolid
-> inner join test.userid_info as m on a.userid=m.userid
-> inner join test.tbl_userlogin_info_tmp2 as n on a.userid=n.userid
-> right join test.school_id_new as f on d.schoolid=f.schoolid group by f.schoolid;
+----+-------------+-------+--------+-----------------------------------+------------+---------+-----------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-----------------------------------+------------+---------+-----------------------+--------+---------------------------------+
| 1 | SIMPLE | f | ALL | NULL | NULL | NULL | NULL | 2580 | Using temporary; Using filesort |
| 1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 8 | test.f.schoolid | 1 | |
| 1 | SIMPLE | n | index | idx_userid | idx_userid | 5 | NULL | 652751 | Using index |
| 1 | SIMPLE | a | ref | GCID_UserID,Index 2 | Index 2 | 5 | test.n.userid | 1 | Using index |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 8 | cw_relations.a.GCID | 1 | Using index |
| 1 | SIMPLE | m | eq_ref | PRIMARY | PRIMARY | 4 | cw_relations.a.UserID | 1 | |
| 1 | SIMPLE | c | eq_ref | PRIMARY,SchoolID_PeriodID_GradeID | PRIMARY | 8 | cw_relations.b.ID | 1 | |
+----+-------------+-------+--------+-----------------------------------+------------+---------+-----------------------+--------+---------------------------------+
可以看出此语句在tbl_userlogin_info_tmp2表上虽然显示使用了索引,但扫描行数依然为652751 条,为全表扫描:
再看我给tbl_userlogin_info_tmp2表加上自增主键列
alter table tbl_userlogin_info_tmp2 add id int auto_increment primary key ;
mysql> desc tbl_userlogin_info_tmp2;
+--------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+----------------+
| userid | int(11) | YES | MUL | NULL | |
| p | bigint(21) | NO | | 0 | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+--------+------------+------+-----+---------+----------------+
执行计划:
mysql> desc select f.schoolid,d.schoolname,count(*) as numbers,f.manager
-> from cw_relations.cw_groupclassmember as a
-> inner join cw_relations.cw_groupclass as b on a.gcid=b.id
-> inner join cw_relations.cw_class as c on b.id=c.cid
-> inner join cw_relations.cw_school as d on c.schoolid=d.schoolid
-> inner join test.userid_info as m on a.userid=m.userid
-> inner join test.tbl_userlogin_info_tmp2 as n on a.userid=n.userid
-> right join test.school_id_new as f on d.schoolid=f.schoolid group by f.schoolid;
+----+-------------+-------+--------+-----------------------------------+---------------------------+---------+-------------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-----------------------------------+---------------------------+---------+-------------------------+------+---------------------------------+
| 1 | SIMPLE | f | ALL | NULL | NULL | NULL | NULL | 2580 | Using temporary; Using filesort |
| 1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 8 | test.f.schoolid | 1 | |
| 1 | SIMPLE | c | ref | PRIMARY,SchoolID_PeriodID_GradeID | SchoolID_PeriodID_GradeID | 9 | cw_relations.d.SchoolID | 13 | Using index |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 8 | cw_relations.c.CID | 1 | Using index |
| 1 | SIMPLE | a | ref | GCID_UserID,Index 2 | GCID_UserID | 9 | cw_relations.b.ID | 58 | Using index |
| 1 | SIMPLE | m | eq_ref | PRIMARY | PRIMARY | 4 | cw_relations.a.UserID | 1 | |
| 1 | SIMPLE | n | ref | idx_userid | idx_userid | 5 | cw_relations.a.UserID | 1 | Using index |
+----+-------------+-------+--------+-----------------------------------+---------------------------+---------+-------------------------+------+---------------------------------+
可以看出执行计划显示走了索引,扫描行数也减少到了5行
其中原理我还未曾想明白,最开始的表没有自增主键列,而且我也没有给userid这个列设主键列,所以innodb应该会给表创建隐藏主键列,所以猜想效果应该是一样的,但事实胜于雄辩,可见自增主键列对Innodb表来说有多么重要!!
本文出自 “夫臣” 博客,请务必保留此出处http://fucheng.blog.51cto.com/2404495/1571358
一次innodb自增主键重要性案例