MySQL 二級索引會不會自動補齊主鍵

來源:互聯網
上載者:User

MySQL 二級索引會不會自動補齊主鍵

開篇:一直對MySQL 二級索引是否自動加入主鍵問題有懷疑,今天又時間就5.5和5.6分析了一把:

mysql>  select  version(); +------------+ | version()  | +------------+ | 5.6.16-log | mysql> create table t9(     ->  id  int not null ,     -> a int ,     -> b int,     -> c int,     -> primary key( id ),     -> key ab_idx(a,b)     -> )engine=innodb; Query OK, 0 rows affected (0.00 sec) show variables like  '%optimizer_swit%' ; ....  use_index_extensions=off mysql> alter table t9 drop primary key ; Query OK, 16 rows affected (0.01 sec) Records: 16  Duplicates: 0  Warnings: 0  mysql> alter table t9 add primary key( id ,id2); mysql> desc  select  * from t9 where a=2 and b=1 order by  id ; +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ id  | select_type | table |  type  | possible_keys | key    | key_len | ref         | rows | Extra       | +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ |  1 | SIMPLE      | t9    | ref  | ab_idx        | ab_idx | 10      | const,const |    3 | Using where | +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ 1 row  in  set  (0.00 sec)  mysql> desc  select  * from t9 where a=2 and b=1 order by  id ,id2; +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ id  | select_type | table |  type  | possible_keys | key    | key_len | ref         | rows | Extra       | +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ |  1 | SIMPLE      | t9    | ref  | ab_idx        | ab_idx | 10      | const,const |    3 | Using where | +----+-------------+-------+------+---------------+--------+---------+-------------+------+-------------+ * 發現是會自動補齊 mysql>  select  version();  +------------+ | version()  | +------------+ | 5.5.36-log | mysql> CREATE TABLE t01 (     ->   a char(32) not null,     ->   b char(32) not null,     ->   c char(32) not null,     ->   d char(32) not null,     ->   PRIMARY KEY (a,b),     ->    KEY idx2 (d,b)     -> ) Engine=InnoDB; mysql> explain  select  * from t01 where d= 'w'  and b= 'g'  order by a;                                                                    +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+ id  | select_type | table |  type  | possible_keys | key  | key_len | ref         | rows | Extra       | +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+ |  1 | SIMPLE      | t01   | ref  | idx2          | idx2 | 192     | const,const |    3 | Using where | +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+ 1 row  in  set  (0.00 sec)  mysql> explain  select  * from t01 where d= 'w'  and b= 'g'  order by a,b; +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+ id  | select_type | table |  type  | possible_keys | key  | key_len | ref         | rows | Extra       | +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+ |  1 | SIMPLE      | t01   | ref  | idx2          | idx2 | 192     | const,const |    3 | Using where | +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+

MySQL 5.6.16 源碼 storage/innobase/dict/dict0dict.cc

/*******************************************************************/ /** Builds the internal dictionary cache representation for a clustered index, containing also system fields not defined by the user. @return own: the internal representation of the clustered index */ static dict_index_t* dict_index_build_internal_clust( /*============================*/     const  dict_table_t*    table,  /*!< in: table */     dict_index_t*      index)  /*!< in: user representation of                     a clustered index */ {     dict_index_t*  new_index;     dict_field_t*  field;     ulint      trx_id_pos;     ulint      i;     ibool*      indexed;      ut_ad(table && index);     ut_ad(dict_index_is_clust(index));     ut_ad(mutex_own(&(dict_sys->mutex)));     ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);      /* Create a new index object with certainly enough fields */     new_index = dict_mem_index_create(table->name,                       index->name, table->space,                       index->type,                       index->n_fields + table->n_cols);     /* Remember the table columns already contained in new_index */     indexed =  static_cast <ibool*>(         mem_zalloc(table->n_cols *  sizeof  *indexed));      /* Mark the table columns already contained in new_index */     for  (i = 0; i < new_index->n_def; i++) {          field = dict_index_get_nth_field(new_index, i);          /* If there is only a prefix of the column in the index         field, do not mark the column as contained in the index */          if  (field->prefix_len == 0) {              indexed[field->col->ind] = TRUE;         }     }

總結:

1.從原始碼看出在引擎層是做了主動補齊主鍵到二級索引的最後面,但是server層並不知道主鍵補齊到後面,mysql server層不一定動能自動識別二級索引後面的主鍵列,強烈建議建立二級索引的時候加上主鍵列。

2.我上面的示範執行個體M ySQL server層是自動自動識別了二級索引後的主鍵列,看運氣吧,目前還沒遇到過不識別的。

--------------------------------------分割線 --------------------------------------

Ubuntu 14.04下安裝MySQL

《MySQL權威指南(原書第2版)》清晰中文掃描版 PDF

Ubuntu 14.04 LTS 安裝 LNMP Nginx\PHP5 (PHP-FPM)\MySQL

Ubuntu 14.04下搭建MySQL主從伺服器

Ubuntu 12.04 LTS 構建高可用分布式 MySQL 叢集

Ubuntu 12.04下原始碼安裝MySQL5.6以及Python-MySQLdb

MySQL-5.5.38通用二進位安裝

--------------------------------------分割線 --------------------------------------

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.