什么时候需要给字段添加索引:
-表中该字段中的数据量庞大
-经常被检索,经常出现在where子句中的字段
-经常被DML操作的字段不建议添加索引---InnoDB的secondary index使用b+tree来存储,因此在UPDATE、DELETE、INSERT的时候需要对b+tree进行调整,过多的索引会减慢更新的速度
不在低基数列上建立索引,例如“性别”;不在索引列进行数学运算和函数运算;不要索引常用的小型表
索引等同于一本书的目录
主键会自动添加索引,所以尽量根据主键查询效率较高。
如经常根据sal进行查询,并且遇到了性能瓶颈,首先查看程序是否存算法问题,再考虑对sal建立索引
P即primary
,主键的意思---F即foreign key
,外键的意思----M即mandatory
,强制不可为空的意思
/*结论唯一索引与唯一约束一样没什么鸟不同(还没遇到) 删约束就是删索引,删索引就是删约束*/
/*在添加索引或者唯一索引的组合索引时 key---MUL */
alter table Stu add index in_name(name);
alter table Stu add unique(id,name);
/*在添加唯一索引或者唯一约束时 key---uni */
alter table Stu add unique index(name);
alter table Stu add unique(name);
应该说是 key 属性 --PRI主键约束;UNI唯一约束;MUL可以重复。
1. 如果Key是空的, 那么该列值的可以重复, 表示该列没有索引, 或者是一个非唯一的复合索引的非前导列
2. 如果Key是PRI, 那么该列是主键的组成部分
3. 如果Key是UNI, 那么该列是一个唯一值索引的第一列(前导列),并别不能含有空值(NULL)
4. 如果Key是MUL, 那么该列的值可以重复, 该列是一个非唯一索引的前导列(第一列)或者是一个唯一性索引的组成部分但是可以含有空值NULL
如果对于一个列的定义,同时满足上述4种情况的多种,比如一个列既是PRI,又是UNI
那么"desc 表名"的时候,显示的Key值按照优先级来显示 PRI->UNI->MUL
那么此时,显示PRI
一个唯一性索引列可以显示为PRI,并且该列不能含有空值,同时该表没有主键
一个唯一性索引列可以显示为MUL, 如果多列构成了一个唯一性复合索引
因为虽然索引的多列组合是唯一的,比如ID+NAME是唯一的,但是没一个单独的列依然可以有重复的值
只要ID+NAME是唯一的即可
查看索引 show index from 数据库表名
PRIMARY KEY(主键索引)---alter table Student add primary key()
UNIQUE(唯一索引) ---alter table Stu add unique(dept)
INDEX(普通索引)---alter table Stu add index in_name(name)
FULLTEXT(全文索引)---alter table Stu add fulltext(txt_temp)
普通索引。组合索引-------alter table Stu add index in_name_age(name,age) 它没有任何限制。
唯一索引。组合索引-------alter table Stu add unique(name,age) 自动给你设置唯一索引名字 ///或者自己些 alter table Stu add constraint uni_name_age unique(name,age)--索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
MySQL 中唯一约束是通过唯一索引实现的,为了保证没有重复值,在插入新记录时会再检索一遍,怎样检索快,当然是建索引了,所以,在创建唯一约束的时候就创建了唯一索引。
1、唯一约束和唯一索引,都可以实现列数据的唯一,列值可以有null。
2、创建唯一约束,会自动创建一个同名的唯一索引,该索引不能单独删除,删除约束会自动删除索引。唯一约束是通过唯一索引来实现数据的唯一。
3、创建一个唯一索引,这个索引就是独立,可以单独删除。
4、如果一个列上想有约束和索引,且两者可以单独的删除。可以先建唯一索引,再建同名的唯一约束。
5、如果表的一个字段,要作为另外一个表的外键,这个字段必须有唯一约束(或是主键),如果只是有唯一索引,就会报错。
约束是业务检查,比方说非空约束,check约束,那是检查字段非空,是否符合check。而索引是一种数据结构,
rowid与字段值的键值对. 两个东西的效果是一样。但:在建立唯一约束时,会自动创建一个唯一索引.并且,失效该约束时,索引自动删除.而创建唯一索引则不会自动创建唯一约束.因此在建表时,如果要创建唯一索引,最好先建唯一索引再创建唯一约束.这样的话,在进行大批量数据插入时,可以先失效约束,插入完成后再进行索引重建.
除了引文中提到的,要被外键引用必须有唯一约束,还有这个区别:索引的键不一定要和唯一约束完全匹配,唯一约束可以只用索引的前导列。
多列索引
1.普通索引。
这是最基本的索引,它没有任何限制。它有以下几种创建方式:
(1)创建索引:CREATE INDEX indexName ON
tableName(tableColumns(length));如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB
和 TEXT 类型,必须指定length,下同。
(2)修改表结构:ALTER tableName ADD INDEX [indexName] ON (tableColumns(length))
(3)创建表的时候直接指定:CREATE TABLE tableName ( [...], INDEX [indexName] (tableColumns(length)) ;
2.唯一索引。
它与前面的"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
(1)创建索引:CREATE UNIQUE INDEX indexName ON tableName(tableColumns(length))
(2)修改表结构:ALTER tableName ADD UNIQUE [indexName] ON (tableColumns(length))
(3)创建表的时候直接指定:CREATE TABLE tableName ( [...], UNIQUE [indexName] (tableColumns(lengt
索引的优点
索引可以让服务器快速定位到表的指定位置。B-Tree索引,按照顺序存储数据,可以用于order by 和Group by 操作。因为数据是
有序的,所有B-tree也就会奖相关的列值存储在一起。优点如下:
- 索引大大减少了服务器扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 将随机IO变为顺序IO
存储引擎用于快速找到记录的一种数据结构。
索引类型
索引有很多种类型,如:B-tree索引、哈希索引、空间数据索引R-TREE 、全文索引、主键索引等,在Mysql
中,索引是在存储引擎层而不是服务器层实现的。所以没有统一的索引标准——不同存储引擎的索引工作方式并
不一样,也不是所有存储引擎都支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层实现
也可能不一样。
B-Tree索引
讨论索引的时候,如果没有特别的指明类型,那么多半说的是B-Tree索引,它使用B-Tree数据结构来存储数据。
实际很多存储引擎使用的是B+Tree,即每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点
的范围遍历。
存储引擎不同的方式使用B-Tree索引,性能也各有不同,各有优劣。如:MyISAM使用前缀压缩技术使得索引更小,
但是InnoDB则按照原数据格式进行存储。 MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键
引用被索引的行
- B-Tree索引查询类型
B-Tree适用于全键值、键值范围,或者键前缀查找。
哈希索引
Hash Index 基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算
一个哈希码,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,
同时在哈希表中保存指向每个数据行的指针。
InnoDB引擎有一个特殊功能叫“自适应哈希索引,当InnoDB某些索引值被使用得非常频繁时,也在内存中基于B-Tree索引之上
再创建一个哈希索引。这样就让Btree索引也具有哈希索引的一些优点。这是一个完全自动的,内部的行为,用户无法控制或者
配置,不过如果有必要完全可以关闭该功能。
- 创建自定义的Hash Index
SELECT id FROM url_tbl WHERE url="http://baidu.com"
SELECT id FROM url_tbl WHERE url_crc=CRC32("http://baidu.com")
如果采用这种方式,记住不要使用SHA1和MD5()作为哈希函数,因为这两函数计算出非常长的字符串,会浪费大量的空间,比较时
也会更慢。两函数设计目标是最大限度消除冲突,但这里并不需要这样高的要求。如果数据表非常大,CRC32会出现大量的哈希冲突,
则可以考虑自己实现一个简单的64痊哈希函数。
R-Tree
MyISAM引擎支持空间索引,可以用作地理数据存储。
全文索引
全文索引是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接索引中的值。全文搜索和其他几类索引的匹配方式完全不
一样。它有很多需要注意的,如停用词、词干、复数、布尔搜索等。