MySQL索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。
拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。
索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
——菜鸟教程
索引的简单操作
普通索引
- 添加
CREATE INDEX indexName ON table_name (column_name)
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。
- 创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX indexName (username(16))
);
- 修改表结构(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
- 删除索引的语法
DROP INDEX [indexName] ON mytable;
唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
- 创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length)) - 修改表结构
ALTER table mytable ADD UNIQUE [indexName] (username(length)) - 创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);
索引设计原则
索引的设计可以遵循一些已有的原则,创建索引的时候请尽量考虑符合这些原则,便于提升索引的使用效率,更高效的使用索引。
-
对查询频次较高,且数据量比较大的表建立索引。
-
索引字段的选择,最佳候选列应当从where子句的条件中提取,如果where子句中的组合比较多,那么应当挑选最常用、过滤效果最好的列的组合。
-
使用唯一索引,区分度越高,使用索引的效率越高。
-
索引可以有效的提升查询数据的效率,但索引数量不是多多益善,索引越多,维护索引的代价自然也就水涨船高。对于插入、更新、删除等DML操作比较频繁的表来说,索引过多,会引入相当高的维护代价,降低DML操作的效率,增加相应操作的时间消耗。另外索引过多的话,MySQL也会犯选择困难病,虽然最终仍然会找到一个可用的索引,但无疑提高了选择的代价。
-
使用短索引,索引创建之后也是使用硬盘来存储的,因此提升索引访问的I/O效率,也可以提升总体的访问效率。假如构成索引的字段总长度比较短,那么在给定大小的存储块内可以存储更多的索引值,相应的可以有效的提升MySQL访问索引的I/O效率。
-
利用最左前缀,N个列组合而成的组合索引,那么相当于是创建了N个索引,如果查询时where子句中使用了组成该索引的前几个字段,那么这条查询SQL可以利用组合索引来提升查询效率。
对于索引的一些理解
MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。因为BTree索引是平常使用MySQL时主要打交道的索引,所以谈谈BTree索引的一些理解。
这里笔者也是大言不惭的发表自己的看法,涉及原理的部分先不做过程解释。
首先索引的功能就是为了提高搜索的效率,因为顺序查找这种东西在数据量大的时候,效率非常低。这也决定了索引的用武之地,就是大数据量的时候的检索任务。
主键也是索引,当索引添加的字段出现在where子句中,检索效率会显著提升。
而索引使用存储结构就是Btree结构,还分B-tree和B+tree,一般使用B+tree较多。
B-tree和B+tree最显著的区别就是在于B-tree的叶节点携带数据。
而B+tree只有叶子节点携带数据。
为什么使用BTree,而不使用检索效率更高的其他数据结构。因为检索时间等于内存检索时间和I/O存取时间的和,而I/O存取时间是远远大于内存检索时间的,所以内存检索时间因数据结构不同的差异是微不足道的。而BTree在I/O存取时间上的优势,就让内存检索时间上的劣势不那么明显了,综合来看BTree仍然是最合适的索引的数据结构。
参考文献:
MySQL索引背后的数据结构及算法原理
runoob.com/mysql/mysql-index.html
https://www.cnblogs.com/dylan123/articles/13061152.html