mysql聚集索引 mysql如何查看某个表的聚集索引

转自:https://www.5axxw.com/wenku/ox/1100175x.html

我们知道InnoDB是索引组织表,每个表都有一个聚集索引,那么我们怎么能看出一个表的聚集索引是什么呢?在MySQL5.6版本我们可以利用innodb_table_monitor来观察每个表创建时期选择的聚集索引,今天我们就利用这个黑科技来观察下MySQL是如何来选择每个表的聚集索引的。

【测试查看】

创建表innodb_table_monitor

mysql> create table innodb_table_monitor(id int);
Query OK, 0 rows affected, 1 warning (0.07 sec)

 

创建测试表1(显示指定主键)

mysql> create table t(id int auto_increment,name varchar(10),primary key(id));
Query OK, 0 rows affected (0.02 sec)

 

过大概10几秒,通过查看error.log可以观察到

TABLE: name test/t, id 23, flags 1, columns 5, indexes 2, appr.rows 0
  COLUMNS: id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 30; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7; 
  INDEX: name PRIMARY, id 25, fields 1/4, uniq 1, type 3
   root page 3, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  id DB_TRX_ID DB_ROLL_PTR name
  INDEX: name idx_name, id 26, fields 1/2, uniq 2, type 0
   root page 4, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  name id

 

从上面可以看到InnoDB选择了主键id作为唯一索引,而索引idx_name为普通索引

 

创建测试表2(不指定主键且指定一个非空唯一索引)

mysql> create table t1(id int ,name varchar(10) not null,unique key idx_name(name));
Query OK, 0 rows affected (0.01 sec)

查看error.log

TABLE: name test/t1, id 25, flags 1, columns 5, indexes 1, appr.rows 0
  COLUMNS: id: DATA_INT DATA_BINARY_TYPE len 4; name: DATA_VARMYSQL DATA_NOT_NULL len 30; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7; 
  INDEX: name idx_name, id 29, fields 1/4, uniq 1, type 3
   root page 3, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  name DB_TRX_ID DB_ROLL_PTR id

从日志看到,聚集索引选择的是idx_name

 

创建测试表3(不指定主键也无非空唯一索引)

mysql> create table t2(id int ,name varchar(10),key idx_name(name));
Query OK, 0 rows affected (0.02 sec)

 

TABLE: name test/t2, id 26, flags 1, columns 5, indexes 2, appr.rows 0
  COLUMNS: id: DATA_INT DATA_BINARY_TYPE len 4; name: DATA_VARMYSQL len 30; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7; 
  INDEX: name GEN_CLUST_INDEX, id 30, fields 0/5, uniq 1, type 1
   root page 3, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  DB_ROW_ID DB_TRX_ID DB_ROLL_PTR id name
  INDEX: name idx_name, id 31, fields 1/2, uniq 2, type 0
   root page 4, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  name DB_ROW_ID

从日志可以看出,InnoDB选择的是rowid作为聚集索引

 

创建测试表4(包含以上三种索引)

mysql> create table t3(id int auto_increment,name1 varchar(10) not null,name2 varchar(10),primary key(id),unique key idx_name1(name1),key idx_name2(name2));
Query OK, 0 rows affected (0.02 sec)

 

TABLE: name test/t3, id 27, flags 1, columns 6, indexes 3, appr.rows 0
  COLUMNS: id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name1: DATA_VARMYSQL DATA_NOT_NULL len 30; name2: DATA_VARMYSQL len 30; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7; 
  INDEX: name PRIMARY, id 32, fields 1/5, uniq 1, type 3
   root page 3, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  id DB_TRX_ID DB_ROLL_PTR name1 name2
  INDEX: name idx_name1, id 33, fields 1/2, uniq 1, type 2
   root page 4, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  name1 id
  INDEX: name idx_name2, id 34, fields 1/2, uniq 2, type 0
   root page 5, appr.key vals 0, leaf pages 1, size pages 1
   FIELDS:  name2 id

从日志看出,InnoDB还是选择的是主键作为聚集索引

 

5.7查看聚集索引的方法

因为5.7已经把innodb_table_monitor的功能移除,我们只能通过视图来观察,观察方法如下:

root@127.0.0.1:3306  [information_schema]>create table xucl.tttt(id int,name1 varchar(10) not null,name2 varchar(10),unique key idx_name1(name1),key idx_name2(name2),primary key(id));
Query OK, 0 rows affected (0.02 sec)

root@127.0.0.1:3306  [information_schema]>select i.* from INNODB_SYS_INDEXes i join INNODB_SYS_TABLES t on i.table_id=t.table_id where [图片]t.name='xucl/tttt';
+----------+-----------+----------+------+----------+---------+-------+-----------------+
| INDEX_ID | NAME      | TABLE_ID | TYPE | N_FIELDS | PAGE_NO | SPACE | MERGE_THRESHOLD |
+----------+-----------+----------+------+----------+---------+-------+-----------------+
|      104 | PRIMARY   |       64 |    3 |        1 |       3 |    64 |              50 |
|      105 | idx_name1 |       64 |    2 |        1 |       4 |    64 |              50 |
|      106 | idx_name2 |       64 |    0 |        1 |       5 |    64 |              50 |
+----------+-----------+----------+------+----------+---------+-------+-----------------+
3 rows in set (0.00 sec)

通过视图看到每个表的第一个索引即聚集索引

 

 

总结:

InnoDB在选择聚集索引的优先级上符合以下顺序

  • 如果InnoDB表显示地指定了主键,那么会选择主键作为聚集索引

  • 如果InnoDB表没有显示指定主键,那么会优先选择第一个非空唯一索引作为聚集索引

  • 如果以上条件都不满足,那么InnoDB会选择一个隐式的6字节rowid作为聚集索引

上一篇:python小技巧大应用--实测aiohttp可正常运行的写法


下一篇:IDEA建Web项目使用Tomcat时,出现HTTP Status 404 情况的一种解决方法(自我留档)