索引就好像数的目录一样,如果在字段中建立索引,那么以索引列为查询条件时可以加快查询数据的速度,这是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后面的选择列,另外我们要尽量选择在唯一值多的大表上面创建索引。