前言

查看索引

查看表中已经存在 index:show index from table_name;

创建和删除索引

索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引。删除索引可以利用ALTER TABLE或DROP INDEX语句来实现。

(1)使用ALTER TABLE语句创建索引。

语法如下:

alter table table_name add index index_name (column_list) ; 
 alter table table_name add unique (column_list) ; 
  alter table table_name add primary key (column_list) ;

其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3种创建索引的格式,table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。索引名index_name可选,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以同时创建多个索引。

创建索引的示例如下:

mysql> use tpsc 
 Database changed 
 mysql> alter table tpsc add index shili (tpmc ) ; 
  Query OK, 2 rows affected (0.08 sec) 
Records: 2 Duplicates: 0 Warnings: 0

(2)使用CREATE INDEX语句对表增加索引。

能够增加普通索引和UNIQUE索引两种。其格式如下:

create index index_name on table_name (column_list) ; 
 create unique index index_name on table_name (column_list) ;

说明:table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名不可选。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。

(3)删除索引。

删除索引可以使用ALTER TABLE或DROP INDEX语句来实现。DROP INDEX可以在ALTER TABLE内部作为一条语句处理,其格式如下:

drop index index_name on table_name ; 
 alter table table_name drop index index_name ; 
  alter table table_name drop primary key ;

其中,在前面的两条语句中,都删除了table_name中的索引index_name。而在最后一条语句中,只在删除PRIMARY KEY索引中使用,因为一个表只可能有一个PRIMARY KEY索引,因此不需要指定索引名。如果没有创建PRIMARY KEY索引,但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。

如果从表中删除某列,则索引会受影响。对于多列组合的索引,如果删除其中的某列,则该列也会从索引中删除。如果删除组成索引的所有列,则整个索引将被删除。

删除索引的操作,如下面的代码:

mysql> drop index shili on tpsc ; 
 Query OK, 2 rows affected (0.08 sec) 
 Records: 2 Duplicates: 0 Warnings: 0

该语句删除了前面创建的名称为“shili”的索引。

索引类型

mysql支持的存储引擎:Innodb MyIsam NDB Memory Archive。

mysql索引按存储结构:

支持4种索引分别是:full-text,b-tree,hash,r-tree。

mysql索引按值特性:唯一 普通 主键

mysql索引按表列数:

分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列

MySQL索引类型包括:

(1)普通索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

(2)唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

(3)主键索引

它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引

(4)组合索引

为了形象地对比单列索引和组合索引,为表添加多个字段:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL ); 为了进一步榨取MySQL的效率,就要考虑建立组合索引。就是将 name, city, age建到一个索引里:

ALTER TABLE mytable ADD INDEX name_city_age (username(10),city,age); 建表时,usernname长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。

如果分别在 usernname,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。

建立这样的组合索引,其实是相当于分别建立了下面三组组合索引:

usernname,city,age usernname,city usernname 为什么没有 city,age这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,下面的几个SQL就会用到这个组合索引:

SELECT * FROM mytable WHREE username="admin" AND city="郑州" SELECT * FROM mytable WHREE username="admin" 而下面几个则不会用到: 
  SELECT * FROM mytable WHREE age=20 AND city="郑州" SELECT * FROM mytable WHREE city="郑州"

(5)索引优化-full-text索引

full-text为全文索引,在mysql里仅有myisam支持它,而且支持full-text的字段只有char、varchar、text数据类型。 
 full-text主要是用来代替like "%***%"效率低下的问题 
  solr sphinx 全文检索

你是否一直在寻找比MySQL的LIKE语句更高效的方法的,下面我就为你介绍几种。

LIKE语句:SELECT `column` FROM `table` where `condition` like `%keyword%'

事实上,可以使用 locate(position) 和 instr 这两个函数来代替

一、LOCATE语句 :SELECT `column` from `table` where locate(‘keyword’, `condition`)>0

二、或是 locate 的別名 position

POSITION语句:SELECT `column` from `table` where position(‘keyword’ IN `condition`)

三、INSTR语句

SELECT `column` from `table` where instr(`condition`, ‘keyword’ )>0 
  locate、position 和 instr 的差別只是参数的位置不同,同时locate 多一个起始位置的参数外,两者是一样的。 
  mysql> SELECT LOCATE(‘bar’, ‘foobarbar’,5); 
  -> 7

索引的缺点

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点

◆虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

◆建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句

建立索引注意事项

会导致引擎放弃使用索引,改为进行全表的几种情况,都要在开发中尽量避免出现!

(1)、where子句中使用like关键字时,前置百分号会导致索引失效(起始字符不确定都会失效)。如:select id from test where name like "%吉坤"。

(2)、where子句中使用is null或is not null时,因为null值会被自动从索引中排除,索引一般不会建立在有空值的列上。

(3)、where子句中使用or关键字时,or左右字段如果存在一个没有索引,有索引字段也会失效;而且即使都有索引,因为二者的索引存储顺序并不一致,效率还不如顺序全表扫描,这时引擎有可能放弃使用索引,所以要慎用or。

(4)、where子句中使用in或not in关键字时,会导致全表扫描,能使用exists或between and替代就不使用in。

(5)、where子句中使用!=操作符时,将放弃使用索引,因为范围不确定,使用索引效率不高,会被引擎自动改为全表扫描;

(6)、where子句中应尽量避免对索引字段操作(表达式操作或函数操作),比如select id from test where num/2 = 100应改为num = 200。

(7)、在使用复合索引时,查询时必须使用到索引的第一个字段,否则索引失效;并且应尽量让字段顺序与索引顺序一致。

(8)、查询时必须使用正确的数据类型。数据库包含了自动了类型转换,比如纯数字赋值给字符串字段时可以被自动转换,但如果查询时不加引号查询,会导致引擎忽略索引。