mysql 数据库建立索引



索引就好像数的目录一样,如果在字段中建立索引,那么以索引列为查询条件时可以加快查询数据的速度,这是mysql优化的重要内容之一;

创建主键索引

查询数据库,根据主键查询是最快的,每个表只能存在一个主键列,但是可以有多个普通索引列,主键列要求列内的所有内容必须是唯一的,而索引列不要求内容必须唯一。

首先不管是建立主键索引还是普通索引,都要在表的列上面创建,可以对单列创建索引,但是也可以对多列创建索引。



创建索引命令小结

增加主键

命令:alter table 表名 change id id int primary key;

alter table student change id id int primary key;


删除主键:

命令:alter table 表名 drop primary key ;

    alter table student drop primary key ;


建立普通索引

添加索引

命令:alter table 表名 add index 索引名称(需要添加索引的列);

alter table student add index index_name(name);

alter table student add index index_dept(dept);  


删除索引 

命令:alter table 表名 drop index 索引名称;

命令:drop index 索引名称 on 表名; 

alter table student drop index index_name;

alter table student drop index index_dept;   

drop index ind_name_dept on student; 

对字符的前N个字符创建普通索引的语法

命令:create index 索引名称 on 表名(列名(N));

create index index_name8 on student(name(8));

上面条件列前8个字符创建索引

为表创建联合索引

创建索引

命令:create index 索引名称 on 表名(name,dept);

create index ind_name_dept on student(name,dept);

删除索引

命令:drop index 索引名称 on 表名; 

drop index ind_name_dept on student; 

或者:alter table student drop index ind_name_dept;

 

创建唯一非主键索引

命令:create unique index 索引名称 on 表名(列名); 

create unique index index_age on student(age); 


1、要在表的列上创建索引

2、索引会加快查询速度,但是也会影响更新的速度,已经消耗服务器资源

3、索引不是越多越好,要在频繁查询的where后面的条件列上面创建索引

4、要在大表,和唯一值多的列上面创建索引

4、要在大表,和唯一值多的列上面创建索引


建立主键索引的方法

1、在建表时,可以增加建立主键索引的语句。

create table student(

id int(4) not null #auto_increment,

name char(20) not null,

age  tinyint(2) not null default '0',

dept varchar(16) default null,

primary key(id),

key index_name(name)

);

==

create table student(

id int(4) not null  ,

name char(20) not null,

age  tinyint(2) not null default '0',

dept varchar(16) default null,

primary key(id),

key index_name(name)

);


提示:

primary key(id)          《==== 主键

key index_name(name)      《==== name 字段为普通索引

=================

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)


mysql> show create table student\G;

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name` (`name`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 


2、在建立表后通过alter 命令增加主键索引



a、主键不能重复创建,必须先删除上面配置的主机,再配置

  删除主键:alter table student drop primary key ;

  命令:alter table 表名 drop primary key ;

  

mysql> alter table student drop primary key ;

Query OK, 0 rows affected (0.03 sec)

Records: 0  Duplicates: 0  Warnings: 0

删除可能出现下面错误:

mysql> alter table student drop primary key;

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

mysql> 

这是因为主机设置了auto_increment自增参数,所以不能删除。


b、增加主键

   命令:alter table 表名 change id id int primary key;

   alter table student change id id int primary key;


##################################


   mysql> alter table student change id id int primary key;

Query OK, 0 rows affected (0.00 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table student\G;                     

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name` (`name`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> alter table student drop primary key ;           

Query OK, 0 rows affected (0.05 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table student\G;          

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  KEY `index_name` (`name`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> alter table student change id id int primary key auto_increment ;

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table student\G;                                     

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name` (`name`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 

##################################

##################################

##################################


建立普通索引

添加索引

命令:alter table 表名 add index 索引名称(需要添加索引的列);

alter table student add index index_name(name);

alter table student add index index_dept(dept);  


删除索引 

命令:alter table 表名 drop index 索引名称;

命令:drop index 索引名称 on 表名; 

alter table student drop index index_name;

alter table student drop index index_dept;   

drop index ind_name_dept on student; 

##################################


mysql> alter table student add index index_dept(dept);           

Query OK, 0 rows affected (0.05 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> alter table student drop index index_dept;          

Query OK, 0 rows affected (0.10 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table student\G;                    

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 


##################################

##################################

##################################

##################################

对字段的前N个字符创建普通索引

当遇到表中较大的列时,列内容的前N个字符所在内容中已经接近唯一时,这个时候可以对这前N个字符建立索引,而无需对整个列建立索引,这样可以节省创建索引占用系统的空间,从而降低读取和更新索引消耗的系统资源


对字符的前N个字符创建普通索引的语法

命令:create index 索引名称 on 表名(列名(N));

create index index_name on test(name(8));

上面条件列前8个字符创建索引

create index index_name8 on student(name(8)); 

show create table student\G; 

SHOW index from student\G;



======================

mysql> create index index_name8 on student(name(8)); 

Query OK, 0 rows affected (0.05 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> 

mysql> show create table student\G;                  

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name8` (`name`(8))            《===========前8个字符创建的索引

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql

mysql> SHOW index from student\G;

*************************** 1. row ***************************

       Table: student

  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: 

*************************** 2. row ***************************

       Table: student

  Non_unique: 1

    Key_name: index_name8

Seq_in_index: 1

 Column_name: name

   Collation: A

 Cardinality: NULL

    Sub_part: 8

      Packed: NULL

        Null: 

  Index_type: BTREE

     Comment: 

2 rows in set (0.00 sec)


ERROR: 

No query specified


mysql> 


#################################################################

#################################################################

#################################################################


为表创建联合索引

创建索引

create index ind_name_dept on student(name,dept);

show create table student\G; 

删除索引

drop index ind_name_dept on student; 

或者:alter table student drop index ind_name_dept;

#########################################

#########################################

#########################################

mysql> show create table student\G;                     

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name8` (`name`(8)),

  KEY `ind_name_dept` (`name`,`dept`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 



创建前n个字符的联合索引


mysql> create index ind_name_dept on student(name(5),dept);

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table student\G;         

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name8` (`name`(8)),

  KEY `ind_name_dept` (`name`(5),`dept`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 




#################################################################


提示:按条件列查询数据时,联合索引是有前缀生效特性的

index(a,b,c) 仅a,ab,abc三个查询条件列可以走索引,而b,bc,ac,c,等无用使用索引了。



#################################################################

#################################################################

#################################################################

创建唯一非主键索引

create unique index index_age on student(age); 



mysql> create unique index index_age on student(age); 

Query OK, 0 rows affected (0.02 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(11)     | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   | UNI | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)


mysql> show create table student\G;                  

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `index_age` (`age`),

  KEY `index_name8` (`name`(8)),

  KEY `ind_name_dept` (`name`(5),`dept`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


ERROR: 

No query specified


mysql> 



索引列的创建,以及生效条件

问题1、既然索引可以加快查询速度,那么就给所有的列创建索引吗?

解答:因为索引不但占用系统空间,更新数据库还需要维护索引数据的,因此,索引是一把双刃剑,并不是越多越好,例如:数十到几百行的小表无需建立索引,写频繁,读少的业务要少建索引。

问题2、到底哪里列需要建立索引呢?

select user,host from mysql.user where host=“” ,索引一定要创建在条件列而不是select后面的选择列,另外我们要尽量选择在唯一值多的大表上面创建索引。







你可能感兴趣的:(mysql,数据库建立索引)