首页 技术 正文
技术 2022年11月16日
0 收藏 818 点赞 2,472 浏览 7407 个字

Date: 20140207
Auth: Jin

索引是根据表中一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表。

索引的主要作用

  • 快速存取数据
  • 保证数据记录的唯一性
  • 实现表与表之间的参照完整性
  • 在使用ORDER BY,GROUP BY子句进行数据检索时,利用索引可以减少排序和分组的时间。

一、索引结构 Index_type
包括B-Tree,Hash,full-text,R-Tree
1、B-Tree 除Archive存储引擎外其他存储引擎都支持,使用最频繁
2、Hash Memory和NDB Cluster支持,使用较少
3、Full-text 全文索引 仅MyISAM存储引擎支持,且仅有char,varchar,text这三种数据类型的列支持才可以建全文索引
4、R-Tree 解决空间数据检索的问题 使用少

btree索引和hash索引的区别
http://www.cnblogs.com/vicenteforever/articles/1789613.html

二、索引类型
1、UNIQUE KEY 唯一索引
索引列的值必须唯一,但允许有空值。如果是组合索引(可以多个字段组合),则列值的组合必须唯一。一个表可以有多个唯一索引。
可设置索引名

2、PRIMARY KEY 主键索引
一个表只能有一个主键索引,索引字段不能为空,一种特殊的唯一索引。
索引名只能是

3、普通索引
最基本的索引,它没有任何限制
可设置索引名

4、联合索引(组合索引)
多个字段联合组成的普通索引
可设置索引名

三、查看表的索引
1、语句
mysql> show index from table_name;
mysql> show keys from table_name;

mysql> show index from Product;
+———–+————+——————–+————–+————-+———–+————-+———-+——–+——+————+———+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+———–+————+——————–+————–+————-+———–+————-+———-+——–+——+————+———+
| Product | 0 | PRIMARY | 1 | productId | A | 0 | NULL | NULL | | BTREE | |
| Product | 0 | index_UNIQUE | 1 | pname | A | 0 | NULL | NULL | | BTREE | |
| Product | 0 | index_UNIQUE_union | 1 | productId | A | 0 | NULL | NULL | | BTREE | |
| Product | 0 | index_UNIQUE_union | 2 | productName | A | 0 | 5 | NULL | | BTREE | |
| Product | 1 | index_price | 1 | price | A | 0 | NULL | NULL | YES | BTREE | |
| Product | 1 | index_union | 1 | productId | A | 0 | NULL | NULL | | BTREE | |
| Product | 1 | index_union | 2 | pname | A | 0 | NULL | NULL | | BTREE | |
| Product | 1 | index_productName | 1 | productName | A | 0 | 10 | NULL | | BTREE | |
+———–+————+——————–+————–+————-+———–+————-+———-+——–+——+————+———+
8 rows in set (0.00 sec

2、说明
· Table
表的名称。
· Non_unique
如果MySQL索引不能包括重复词,则为0。如果可以,则为1。
· Key_name
索引的名称。
· Seq_in_index #普通索引才可以指定列名称
索引中的列序列号,从1开始。
· Column_name
列名称。
· Collation
列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。
· Cardinality
MySQL索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越
大,当进行联合时,MySQL使用该索引的机会就越大。
· Sub_part
如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。
· Packed
指示关键字如何被压缩。如果没有被压缩,则为NULL。
· Null
如果列含有NULL,则含有YES。如果没有,则该列含有NO。
· Index_type
用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
· Comment

三、创建索引和删除
创建表时创建索引对全部索引都有有效
CREATE TABLE `Product19` (
`productId` int(6) NOT NULL AUTO_INCREMENT,
`pname` varchar(25) NOT NULL,
`productName` varchar(25) NOT NULL,
`created` date DEFAULT ‘2000-01-01’,
`price` int(11) DEFAULT ‘200’,
PRIMARY KEY (`productId`),
UNIQUE KEY `index_UNIQUE` (`pname`),
UNIQUE KEY `index_UNIQUE_union` (`productId`,`productName`(5)),
KEY `index_price` (`price`),
KEY `index_union` (`productId`,`pname`),
KEY `index_productName` (`productName`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

按索引类型分区
(一)UNIQUE KEY 唯一索引
1、添加索引
1)、创建表时创建
create table Product(
productName varchar(25) NOT NULL,
UNIQUE KEY `unique_productName`(productName)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)、修改表-添加新字段为表的唯一索引
alter table Product add productName varchar(25) UNIQUE;

3)、修改表-修改已存在的字段为唯一索引
单字段作为唯一索引
mysql> alter table Product add UNIQUE KEY `unique_pname`(pname);
单个字段的部分字符串作为唯一索引
alter table Product add UNIQUE KEY `unique_pname2`(pname(10));
多个字段联合组成的唯一索引
mysql> alter table Product add UNIQUE KEY `unique_union`(productName,productId);

4)、create index方式添加
也需添加的字段已经存在
CREATE UNIQUE INDEX indexName ON mytable(username(length))
单字段作为唯一索引
mysql> create UNIQUE INDEX `unique_productName` on Product(productName);
单个字段的部分字符串作为唯一索引
mysql> create UNIQUE INDEX `unique_productName1` on Product(productName(5));
多个字段联合组成的唯一索引
mysql> create UNIQUE INDEX `unique_union` on Product(productName,productId);

注意:不管一个字段的部分,还是多个字段组合都必须是唯一的

最好还是创建表时候一起创建,因为键值重复的问题。
mysql> alter table Product add productName varchar(25) NOT NULL UNIQUE;
ERROR 1062 (23000): Duplicate entry ” for key ‘productName’

2、删除索引
删除索引和删除普通索引一样
1)修改表drop
mysql> alter table Product drop index unique_pname;
2)DROP INDEX ON table
DROP INDEX [indexName] ON mytable;
mysql> drop index `unique_union` ON Product;

(二)PRIMARY KEY 主键索引
1、添加索引
1)、创建表时创建
create table Product(
productId int(6) NOT NULL AUTO_INCREMENT,
PRIMARY KEY(productId)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)、修改表-添加新字段为表的主键索引
mysql> alter table Product add productId int(6) NOT NULL PRIMARY KEY;

3)修改表-修改已存在的字段为主键索引
mysql> alter table Product add PRIMARY KEY(productId);

注意:
* CREATE INDEX 无法用在PRIMARY KEY

2、删除索引
修改表drop PRIMARY KEY
mysql> alter table tb1 drop PRIMARY KEY;
注意
* 如果主键索引列是自增无法drop
mysql> alter table Product drop PRIMARY KEY;
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

* DROP INDEX 无法用在PRIMARY KEY

(三)普通索引
1、添加索引
1)、创建表时创建
create table Product(
productName varchar(25) NOT NULL,
KEY `index_productName`(productName)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)、修改表-修改已存在的字段为唯一索引
单字段作为唯一索引
mysql> alter table Product add index `index_productName`(productName);
单个字段的部分字符串作为唯一索引
mysql> alter table Product add index `index_productName`(productName(10));

3)、create index方式添加
也需添加的字段已经存在
CREATE INDEX indexName ON mytable(username(length))
单字段作为唯一索引
mysql> create INDEX `index_productName` on Product(productName);
单个字段的部分字符串作为唯一索引
mysql> create INDEX `index_productName` on Product(productName(10));
mysql> create INDEX `index_productName` on Product11(productName) USING HASH;

注意:无法在修改表-添加新字段为表的唯一索引

2、删除索引
删除索引和删除普通索引一样
1)修改表drop
mysql> alter table Product drop index index_productName;

2)DROP INDEX ON table
DROP INDEX [indexName] ON mytable;
mysql> drop index `index_productName` ON Product

(三)联合索引
联合索引就是多个字段组成的普通索引
1、添加索引
1)、创建表时创建
create table Product(
productId int(6) NOT NULL,
productName varchar(25) NOT NULL,
KEY `union_index;`(productId,productName)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)、修改表-修改已存在的字段为唯一索引
mysql> alter table Product add index union_index(productId,productName);

3)、create index方式添加
也需添加的字段已经存在
CREATE INDEX indexName ON mytable(username(length))
mysql> create index union_index ON Product(productId,productName);
mysql> create index union_index ON Product(productId,productName(10));

2、删除索引
删除索引和删除普通索引一样
1)修改表drop
mysql> alter table Product13 drop index union_index;

2)DROP INDEX ON table
DROP INDEX [indexName] ON mytable;
mysql> drop index union_index on Product;

总结:
1、所有的索引都可以在创建表的时候添加以及修改表(字段已存在)添加
2、修改表-添加新字段为表的索引,只能用于PRIMARY KEY和UNIQUE(不推荐)
3、PRIMARY KEY和UNIQUE KEY最好创建表时候添加(推荐)
4、CREATE INDEX/DROP INDEX,以及alter table TABLENAME drop index只能用于普通索引和UNIQUE,无法用于PRIMARY KEY
5、含有AUTO_INCREMENT且已经有数据的PRIMARY KEY无法删除
6、QUNIUE KEY 注意:不管一个字段的部分,一个字段,还是多个字段组合都必须是唯一的

四、建立索引的时机
需要在什么情况下建立索引呢?
一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。例如:
SELECT a.Name FROM gameusers a LEFT JOIN bbsusers b ON a.Name=b.username WHERE a.age=20 AND a.city=’上海’
此时就需要对city和age建立索引,由于mytable表的userame也出现在了JOIN子句中,也有对它建立索引的必要。

刚才提到只有某些时候的LIKE才需建立索引。因为在以通配符%和_开头作查询时,MySQL不会使用索引。例如下句会使用索引:
SELECT * FROM bbsusers WHERE username like’admin%’
而下句就不会使用:
SELECT * FROM mytable WHEREt Name like’%admin’
因此,在使用LIKE时应注意以上的区别。

五、索引的不足之处和使用索引的注意事项
1、索引的不足之处
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:

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

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

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

2、使用索引的注意事项
使用索引时,有以下一些技巧和注意事项:

1)索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

2)使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查

询速度而且可以节省磁盘空间和I/O操作。

3)索引列排序
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包

含多个列的排序,如果需要最好给这些列创建复合索引。

4)like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

5)不要在列上进行运算
select * from users where YEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01’;

6)不使用NOT IN和<>操作

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,910
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,435
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,250
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,061
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,693
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,731