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和<>操作

MYSQL复习笔记7-索引的更多相关文章

  1. MySQL学习笔记(三)—索引

    一.概述 1.基本概念       在大型数据库中,一张表中要容纳几万.几十万,甚至几百万的的数据,而当这些表与其他表连接后,所得到的新的数据数目更是要大大超出原来的表.当用户检索这么大量的数据时,经 ...

  2. mysql学习笔记--数据库索引

    一.索引的优点:查询速度快 二.索引的缺点: 1. 增.删.改(数据操作语句)效率低了 2. 索引占用空间 三.索引类型: 1. 普通索引 2. 唯一索引(唯一键) 3. 主键索引:只要主键就自动创建 ...

  3. MYSQL复习笔记8-数据完整性

    Date: 20140207Auth: Jin 一.数据完整性的分类数据完整性是指数据库中数据在逻辑上的一致性和准确性.包括三种1.实体完整性又称行的完成性,要求表中有一个主键,其值不能为空且唯一地标 ...

  4. MYSQL复习笔记6-字符集

    Date: 20100101 Auth: Jin 参考http://blog.sina.com.cn/s/blog_9707fac301016wxm.html 一.字符集介绍 计算机只处理二进制代码 ...

  5. MYSQL复习笔记4-基本SQL语句

    Date: 20140115Auth: Jin参考:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#select一:数据库操作1:显示数据 ...

  6. MYSQL复习笔记3-用户和安全

    Date: 20140115Auth: Jin参考:http://dev.mysql.com/doc/refman/5.1/en/security.html 一.权限系统实现方式相关权限信息存储在几个 ...

  7. MYSQL复习笔记2-自带工具介绍

    Date: 20140102Auth: Jin 一.mysql 命令行客户端1)base-h host-P port--socket=path,-S path用于连接的套接字文件替换使用IP PORT ...

  8. MYSQL复习笔记1-物理文件和系统架构

    date:20140101auth:Jin 一.物理组成(一) 日志文件参考:http://dev.mysql.com/doc/refman/5.1/en/server-logs.html1.错误日志 ...

  9. mysql复习笔记

    阅读目录 1.什么是SQL语句2.使用sql语句创建数据库和表3.创建数据表4.数据完整性约束5.四中基本字符类型说明6.SQL基本语句7.类型转换函数8.日期函数9.数学函数10.字符串函数11.联 ...

随机推荐

  1. 【Matlab】绘制饼状统计图

    a=tabulate(b); % b为需要绘制饼图的原始数据列,生成新的一个矩阵a label={'1','2','3'} % 设定饼图每块扇形代表的内容 percent=num2str(a(:,3) ...

  2. java===java基础学习(16)---final

    final-----概念 1.当不希望父类的某个方法被子类覆盖(override)时,可以用final关键字修饰. 2.当不希望类的某个变量的值被修改时,可以用final修饰.如果要用final,则必 ...

  3. Linux内核死锁检测机制【转】

    转自:http://www.oenhan.com/kernel-deadlock-check 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进 ...

  4. 2017多校第8场 HDU 6143 Killer Names 容斥,组合计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6143 题意:m种颜色需要为两段长度为n的格子染色,且这两段之间不能出现相同的颜色,问总共有多少种情况. ...

  5. java 和 JVM

    C++和Java的区别 指针:java中不存在指针的概念,编程者无法直接通过指针来直接访问内存,有利于维护java程序的安全 多重继承:C++支持多重继承,java不支持多重继承,但是允许一个类继承多 ...

  6. git学习笔记三

    1.每个分支的历史版本维护信息位置是.git/logs/refs/heads/master,这个位置的信息是文本文件,不是引用. harvey@harvey-Virtual-Machine:~/dem ...

  7. 【Android开发日记】之基础篇(一)——TextView+SpannableStringBuilder

    TextView是控件中最最基础的一个控件,也是最简单的一个控件.但如果仅此,我不会专门为TextView写一篇文章.最近发现了Android中有趣的一个类,那就是标题上写的SpannableStri ...

  8. 生成RSA2公钥、私钥

    RSA2是一种被使用广泛的非对称加密算法. openssl OpenSSL> genrsa -out app_private_key.pem # 私钥RSA2 OpenSSL> rsa - ...

  9. 【linux】su和sudo命令的区别

    来源:http://www.jb51.net/LINUXjishu/12713.html 一. 使用 su 命令临时切换用户身份 1.su 的适用条件和威力 su命令就是切换用户的工具,怎么理解呢?比 ...

  10. linux命令(1):sed命令

    实例一: Config_file文件内容如下: sed去除注释行:sed -i -c -e '/^#/d' config_file  [会删除指定文件带有注释行] sed去除空行: sed -i -c ...