索引是存储引擎用于快速查找记录的一种数据结构。因此良好的性能非常关键。尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要。在数据量较小且负载较低时,不恰当的索引对性能的影响可能不明显,但当数据量逐渐增大时,性能则会急剧下降。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高几个数量级,“最优”的索引有时比一个“好的”索引性能要好两个数量级。
索引可以包含一个或多个列的值。如果索引包含多个列,那么列的顺序也十分重要,因为mysql只能高效的使用索引的最左前缀列。创建一个包含列个列的索引,和创建两个只包含一列的索引是大不相同的。
在mysql中,索引是存储引擎层而不是服务器层实现的。不同的存储引擎的索引的工作方式并不一样,也不是所有的存储引擎都支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层的实现也不能不同。
一、索引类型
1、B-Tree索引
大多数mysql存储引擎都支持B-Tree索引。存储引擎以不同的方式使用B-Tree索引,性能也各不相同。例如,MyISAM使用前缀压缩技术使得索引更小,但InnoDB则按照原数据格式进行存储。再如MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键引用被索引的行。
B-Tree通常意味着所有的值都按顺序存储的,并且每一个叶子页到根的距离相同。B-Tree索引能够加快访问数据的速度,因为存储引擎不在需要进行全表扫描来获取需要的数据,而是从索引的根节点开始进行搜索。根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找。通过比较节点页的值和要查找的值可以找到适合的指针进入下层子节点,这些指针实际上定义了子节点页中值的下限和上限。最终存储引擎要么找到对应的值,要么改记录不存在。
叶子节点比较特别,他们的指针指向的是被索引的数据,而不是其他的节点页。在根节点和叶子节点之间可能有很多层节点页。树的深度和表的大小直接相关。B-Tree对索引列是顺序组织存储的,所以很适合查找范围数据。例如,在一个基于文本域的索引树上,按字母顺序连续的值进行查找是非常适合的,所以像“找出所有以I到K开头的名字”这样的查找效率会非常高。
B-Tree索引适用于全键值、键值范围或键前缀查找。其中键前缀查找只适用于根据最前缀的查找。前面所述的索引对如下类型的查询有效:①全值匹配。索引中所有列进行匹配;②匹配最左前缀;③匹配列前缀。在满足最左前缀的基础上匹配最左列的开头部分;④配置范围值。最左列的某一范围内的数据;⑤精确匹配最左列并范围匹配最左列的相邻列;⑥只访问索引的查询。需要查询的字段在索引列中都包含,所以在索引的叶子节点上就可以获取到这些列的值,无需查询数据行。因为索引树中的节点是有序的,所以除了按值查找之外,索引还可以用于查找中的order by操作。一般来说,如果b-tree可以按照某种方式查找到值,那么也可以按照某种方式用于排序。所以,如果order by子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求。
下面是一些关于b-tree索引的限制:①如果不是按照索引的最左列开始查找,则无法使用索引;②不能跳过索引中的列;③如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。到这里可以看到前面的索引列的顺序是多么的重要:这些限制和索引列的顺序有关。在优化性能的时候,可能需要使用相同的列但顺序不相同的索引来满足不同类型的查询需求。
2、哈希索引
哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希吗,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
在mysql中,只有memory引擎显示的支持哈希索引。这也是memory引擎表的默认索引类型,memory引擎同时也支持B-Tree索引。并且索引自身只需要存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引的速度非常快。然而,哈希索引也有它的限制:
- 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。不过,访问内存中的行的速度很快,所以大部分情况下这一点对性能的影响并不明显。
- 哈希索引数据并不是按照索引值的顺序存储的,索引也就无法用于排序。
- 哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。
- 哈希索引只支持等值比较查询,包括=、in()、<=>(注意<>和<=>是不同的操作)。也不支持任何范围查询。
- 访问哈希索引的数据非常快,除非有很多哈希冲突。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。
- 如果哈希冲突很多的话,一些索引维护操作的代价也会很高。
因为这些限制,哈希索引只适用于某些特定的场合。而一旦适合哈希索引,则他带来的性能提升非常显著。除了memory引擎外,NDB集群引擎也支持唯一哈希索引。InnoDB引擎有一个特殊的功能叫做“自适应哈希索引”,当InnoDB注意到某些索引值被使用的非常频繁时,他会在内存中基于b-tree索引之上再创建一个哈希索引,这样就让b-tree索引也具有哈希索引的一些优点。
3、空间数据索引(R-Tree)
MyISAM表支持空间索引,可以用作地理数据存储。和B-Tree索引不同,这类索引无需前缀查询。空间索引会从所有维度来索引数据。查询时,可以有效的使用任意维度来组合查询。必须使用mysql的GIS相关函数来维护数据。
4、全文索引
全文索引是一种特殊类型的索引,他查找的是文本中的关键词,而不是直接比较索引中的值。全文搜索和其他几类索引的匹配方式完全不一样。他有许多需要注意的细节,如停用词、词干和负数、布尔搜索等。全文索引更类似于搜索引擎的事情,而不是简单的where条件匹配。
在相同的列上同时创建全文索引和基于值的b-tree索引不会有冲突,全文索引适用于match against操作,而不是普通的where条件操作。
二、索引优点
索引可以让服务器快速定位到表的指定位置。但是这并不是索引的唯一作用,到目前为止可以看到,根据索引的数据结构不同,索引也有一些其他的附件作用。
常见的b-tree索引,按照顺序存储数据,所以mysql可以用来做order by和group by操作。因为数据是有序的,所以b-tree也就会将相关的列值都存储在一起。最后,因为索引中存储了实际的列值,所以某些查询只使用索引就能够完成全部查询。据此特性,总结下来索引有如下三个优点:
- 索引大大减少了服务器需要扫描的数据量;
- 索引可以帮助服务器避免排序和临时表;
- 索引可以将随机I/O变为顺序I/O;
注意:索引是最好的解决方案吗?
索引并不总是最好的工具。总的来说,只有当索引帮助存储引擎快速查找到记录带来的好处大于其带来的额外工作时,索引才是有效的。对于非常小的表,大部分情况下简单的全表扫描更高效。对于中到大表,索引就非常有效。但对于特大型的表,建立和使用索引的代价将随之增长。这种情况下,则需要一种技术可以直接区分出查询需哟的一组数据,而不是一条记录一条记录的匹配。例如可以使用分区技术。
相关推荐
### MySQL Innodb 索引原理详解 #### 1. 各种树形结构 在深入探讨MySQL Innodb索引之前,我们先了解几种基本的树形数据结构,包括二叉搜索树、B树、B+树以及B*树。 ##### 1.1 搜索二叉树(Binary Search Tree) ...
### MySQL数据库及索引详解 #### 一、MySQL简介与数据库发展 MySQL是一款非常流行的开源关系型数据库管理系统,由瑞典MySQL AB公司开发。它以其高性能、稳定性和易用性著称,广泛应用于Web应用程序和企业级系统中...
MySQL 索引数据结构详解 MySQL 索引是一种特殊的数据结构,它可以帮助快速定位和检索数据。索引的主要目的便是降低树的高度,从而提高查询效率。下面我们将详细介绍 MySQL 索引的数据结构和工作原理。 索引的存储 ...
本文将深入探讨MySQL索引的最佳实践,旨在为开发者和数据库管理员提供实用指南。 ### 理解索引的重要性 索引的存在主要是为了加速数据库中的数据访问速度。在没有索引的情况下,数据库必须遍历整个表来查找特定的...
MySQL 数据库索引详解 MySQL 数据库索引是一种特殊的数据库结构,可以快速查询数据库表中特定记录。索引是提高数据库性能的重要方式。 索引的概念 ---------------- 索引是表中数据的目录。如果使用索引,则扫描...
#### 二、MySQL索引类型详解 ##### 1. B-Tree索引 - **定义**:B-Tree(平衡树)是最常见的索引类型,在大多数情况下使用的索引都属于此类。B-Tree能够支持范围查找、前缀查找以及等值查找等多种操作。 - **特点**...
添加索引的语法为:`ALTER TABLE 表名 ADD 索引类型 索引名称 (列名)`。例如,添加一个名为 `idx_height` 的索引在 `test1` 表的 `height` 列上: ``` ALTER TABLE test1 ADD INDEX idx_height (height); ``` 索引...
### MySQL索引和锁机制详解 #### 一、索引基础 **索引定义:** 索引是MySQL中用于提高查询效率的一种数据结构。通过索引可以在数据表中快速定位到所需的数据行,大大减少不必要的全表扫描。 **索引的重要性:** 1....
1. **普通索引**:最简单的索引类型,只包含单个列。 2. **唯一索引**:确保索引列中的值是唯一的,但允许值为空。 3. **复合索引**:包含多个列的索引,可用于同时基于多个字段进行查询。 4. **聚簇索引(聚集索引...
关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能...
在MySQL数据库中,索引是提高查询效率的关键工具。它们为数据表的列提供了...了解各种索引类型、创建方法和可能导致失效的场景,可以帮助数据库管理员更好地管理和优化他们的数据库,从而提高查询效率和整体系统性能。
- **修改索引**: MySQL不直接支持修改索引,需先删除再重建。 - **查询索引** - **基础命令**: `EXPLAIN SELECT * FROM table_name WHERE condition;` - **参数解释**: - **id**: 指示查询的执行顺序。 - **...
### MySQL索引原理详解 #### 一、索引的基本概念 **索引**是帮助MySQL高效获取数据的数据结构。在数据库中,索引扮演着极其重要的角色,它能够显著提高数据检索的速度,尤其是在处理大规模数据集时尤为重要。索引...
"Explain详解与索引最佳实践"的主题主要聚焦于如何利用MySQL的`EXPLAIN`命令来理解并优化SQL查询,以及如何有效地设计和利用索引来提升查询效率。 `EXPLAIN`是MySQL提供的一种强大工具,用于分析查询执行计划。当你...
总结,理解和熟练运用MySQL索引是数据库管理的关键技能。通过了解索引原理,选择合适的索引类型,优化索引使用,可以显著提高数据库的查询效率,从而提升整个系统的性能。不断实践和学习,你将成为MySQL索引的专家。
1. **选择合适的索引类型**:B-TREE索引适用于范围查询和等值查询,而HASH索引只适用于等值查询。全文索引适合文本搜索。 2. **覆盖索引**:当查询只需要索引中的列时,使用覆盖索引可以避免回表,提高性能。 3. *...