MySQL之索引操作

一、什么是索引

索引就像是书籍的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询速度。常用的索引有:

  • 主键索引
  • 普通索引
  • 联合索引
  • 唯一索引

二、索引的使用

(一)主键索引

查询数据库时,按照主键索引是最快的,主键是唯一的。在创建主键索引时,有两种情况:

1、建表时创建

在创建表时可以创建主键索引。

mysql> create table userinfo(
    -> id int(4) not null auto_increment,
    -> username varchar(32) default null,
    -> age tinyint(2) not null default 0,
    -> primary key(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

通过primary key和auto_increment来创建主键。创建后可以通过desc命令查看:

mysql> desc userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(4)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | YES  |     | NULL    |                |
| age      | tinyint(2)  | NO   |     | 0       |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

2、建表后增加

假如现在的表没有主键,建表语句如下:

create table userinfo(
    id int(4) not null,
    username varchar(32) default null,
    age tinyint(2) not null default 0
);
View Code

现在增加主键:

mysql> alter table userinfo change id id int primary key auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

(二)普通索引

普通索引可以创建多个,它唯一的作用就是加快查询速度,它的创建修改如下:

1、建表时创建

mysql> create table userinfo(
    -> id int(4) not null auto_increment,
    -> username varchar(32) default null,
    -> age tinyint(2) not null default 0,
    -> primary key(id),
    -> KEY index_name(username)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> desc userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(4)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | YES  | MUL | NULL    |                |
| age      | tinyint(2)  | NO   |     | 0       |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

在建表时使用KEY index_name(column)来创建普通索引,注意的是在唯一值多的列上创建索引查询效率更高。

2、建表后增加

-- 删除索引
mysql> alter table userinfo drop index index_name;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看
mysql> desc userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(4)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | YES  |     | NULL    |                |
| age      | tinyint(2)  | NO   |     | 0       |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)

-- 添加索引
mysql> alter table userinfo add index index_username(username);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

3、对字段的前n个字符创建普通索引

   当表中的列的内容比较多时,并且列的内容的前n个字符已经接近唯一时,可以对列的前n个字符建立索引,而无需对整个列建立索引,这样可以节省创建索引占用的系统空间,以及降低读取和更新维护索引消耗的资源。

-- 创建索引的语法
create index index_name on userinfo(username(5))

-- 创建实例
mysql> create index index_username on userinfo(username(5));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引
mysql> show index from userinfoG;
*************************** 1. row ***************************
        Table: userinfo
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: userinfo
   Non_unique: 1
     Key_name: index_username
 Seq_in_index: 1
  Column_name: username
    Collation: A
  Cardinality: 0
     Sub_part: 5
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)

(三)联合索引

如何表中有多个列,可以基于这多个列创建联合索引:

  • 基于多列创建联合索引
  • 基于多列的前n个字符创建联合索引

1、基于多列创建联合索引

-- 删除之前的普通索引
mysql> drop index index_username on userinfo;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 创建联合索引
mysql> create index index_username_age on userinfo(username,age);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引
mysql> show index from userinfoG;
*************************** 1. row ***************************
        Table: userinfo
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: userinfo
   Non_unique: 1
     Key_name: index_username_age
 Seq_in_index: 1
  Column_name: username
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 3. row ***************************
        Table: userinfo
   Non_unique: 1
     Key_name: index_username_age
 Seq_in_index: 2
  Column_name: age
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
3 rows in set (0.01 sec)

 2、基于多列的前n个字符创建联合索引

-- 删除联合索引
mysql> drop index index_username_age on userinfo;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 创建联合索引
mysql> create index index_username_age on userinfo(username(5),age(1));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

3、创建表时创建

create table userinfo(
    id int(4) not null auto_increment,
    username varchar(32) default null,
    age tinyint(2) not null default 0,
    primary key(id),
    KEY index_name(username,age)
);

注意的是按条件列查询数据时,联合索引是有前缀生效特性的,列入index(col1,col2,col3)是col1或者col1,col2或者col1,col2,col3生效,其余的比如col2,col3等不生效。

(四)唯一索引

如果想创建某列或者几列的值是唯一的,那么可以创建唯一非主键索引。

--  创建唯一非主键索引
mysql> create unique index index_uni_username on userinfo(username);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0


--  查看表结构
mysql> desc userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(4)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | YES  | UNI | NULL    |                |
| age      | tinyint(2)  | NO   |     | 0       |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

三、总结

(一)索引的创建与生效条件

  索引虽然可以加快查询速度,但是并非可以将所有的列都加上索引。因为索引不但占用系统空间,而且在更新数据库时还需要维护索引数据。所以对于小表(几百行)以及读取少,写的多的业务没有必要建立索引。

  对于select username,age where id = ...这样的语句,索引列应该建立在where语句后的列上,而非建立在select这样的查询列上。另外就是尽量将索引建立在唯一值多的列上面。

(二)创建索引的命令

-- create或者alter均可

-- 创建主键索引
alter table userinfo change id id int primary key auto_increment
-- 删除主键索引
alter table userinfo drop primary key

-- 创建普通索引
alter table userinfo add index index_username(username)
-- 根据列前n个字符创建普通索引
create index index_username on userinfo(username(5))
-- 删除普通索引
alter table userinfo drop index index_username
drop index index_username on userinfo

-- 根据多个列创建联合索引
create index index_username_age on userinfo(username,age)
-- 根据多个列前n个字符创建联合索引
create index index_username_age on userinfo(username(5),age(1))

-- 创建唯一索引
create unique index index_uni_username on userinfo(username)
原文地址:https://www.cnblogs.com/shenjianping/p/13532580.html