MySQL创建索引
学习mysql,官方文档是最全面的最权威的。
以下英文资料引用自官方文档:
How MySQL Uses Indexes
Indexes are used to find rows with specific(具体) column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. The larger the table, the more this costs. If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading sequentially.
Most MySQL indexes (PRIMARY KEY,UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions are that(特殊的是) indexes on spatial(空间) data types use R-trees(R树), and that MEMORY tables also support hash indexes.
创建主键列(PRIMARY KEY)
CREATE TABLE people_1 (
id int not null AUTO_INCREMENT,
last_name varchar(50) not null,
first_name varchar(50) not null,
dob date not null,
gender enum('m','f') not null,
PRIMARY KEY (id)
)
查看该表索引
mysql> describe people_1;
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| last_name | varchar(50) | NO | | NULL | |
| first_name | varchar(50) | NO | | NULL | |
| dob | date | NO | | NULL | |
| gender | enum('m','f') | NO | | NULL | |
+------------+---------------+------+-----+---------+----------------+
5 rows in set
mysql> show index from people_1;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_1 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set
mysql> show keys from people_1;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_1 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set
现在在first_name,last_name上创建索引,然后查看索引
mysql> create index name_index on people_1(first_name,last_name);
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from people_1;
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_1 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| people_1 | 1 | name_index | 1 | first_name | A | 0 | NULL | NULL | | BTREE | | |
| people_1 | 1 | name_index | 2 | last_name | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set
可以看到表中有三个索引。。
创建表的外键列(FOREIGN KEY)
mysql> CREATE TABLE parent(
id int not null,
primary key (id)
);
CREATE TABLE child(
id int not null,
parent_id int not null,
primary key (id),
foreign key (parent_id) references parent(id)
);
Query OK, 0 rows affected
Query OK, 0 rows affected
mysql>
表child中持有表parent的主键
查看child表的索引
mysql> show index from child;
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| child | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| child | 1 | parent_id | 1 | parent_id | A | 0 | NULL | NULL | | BTREE | | |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set
创建唯一索引(UNIQUE INDEX || UNIQUE KEY)
mysql> CREATE TABLE people_2 (
id int not null,
name varchar(50) not null,
dob date not null,
gender enum('m','f') not null,
primary key(id)
);
Query OK, 0 rows affected
mysql> describe people_2;
+--------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(50) | NO | | NULL | |
| dob | date | NO | | NULL | |
| gender | enum('m','f') | NO | | NULL | |
+--------+---------------+------+-----+---------+-------+
4 rows in set
mysql> show index from people_2;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_2 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set
创建表的唯一索引,索引的名字叫name_unique,在name列上创建唯一索引
mysql> create unique index name_unique on people_2 (name);
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from people_2;
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_2 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| people_2 | 0 | name_unique | 1 | name | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set
创建普通索引(INDEX || KEY)
mysql> CREATE TABLE people_3 (
id int not null,
name varchar(50) not null,
primary key(id),
index (name)
);
Query OK, 0 rows affected
mysql> describe people_3;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(50) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
查看索引
mysql> show index from people_3;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_3 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| people_3 | 1 | name | 1 | name | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set
Non_unique = 1 表示可以包含重复值。
创建全文索引(FULLTEXT)
These are used for full-text searches. Only the InnoDB and MyISAM storage engines support FULLTEXT indexes and only for CHAR, VARCHAR, and TEXT columns.
mysql> CREATE TABLE people_4 (
id int not null,
name varchar(50) not null,
descriptioin varchar(255) not null,
primary key(id)
);
Query OK, 0 rows affected
mysql> describe people_4;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(50) | NO | | NULL | |
| descriptioin | varchar(255) | NO | | NULL | |
+--------------+--------------+------+-----+---------+-------+
3 rows in set
mysql> show index from people_4;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_4 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set
在description列上创建表的全文索引,然后查看索引
mysql> create fulltext index desc_index on people_4 (descriptioin);
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 1
mysql> show index from people_4;
+----------+------------+------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| people_4 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| people_4 | 1 | desc_index | 1 | descriptioin | NULL | 0 | NULL | NULL | | FULLTEXT | | |
+----------+------------+------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set
从上面可以看到,目前为止,索引的存储类型有
Index_type
BTREE
FULLTEXT
创建索引时指定前缀
mysql> CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Query OK, 0 rows affected
mysql> describe test;
+----------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------+------+-----+---------+-------+
| blob_col | blob | YES | MUL | NULL | |
+----------+------+------+-----+---------+-------+
1 row in set
查看索引
mysql> show index from test;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test | 1 | blob_col | 1 | blob_col | A | 0 | 10 | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set
With col_name(N) syntax in an index specification, you can create an index that uses only the first N characters of a string column. Indexing only a prefix of column values in this way can make the index file much smaller. When you index a BLOB or TEXT column, you must specify a prefix length for the index.
注意:Prefix limits are measured in bytes, while the prefix length in CREATE TABLE statements is interpreted as number of characters. Take this into account when specifying a prefix length for a column that uses a multibyte character set.
==========================END=========================