在关系型数据库中,索引(index)是一种单独的、物理层面的对数据库中的一列或多列的值进行排序检索的一种数据结构。
在关系型数据库中,查询数据的效率其实非常低下,在没有做任何优化处理的情况下,查询时,会将表中所有数据全部检查一遍,看每一条数据是否匹配查询条件,所以,数据量越大,查询耗时就越久!并且,数据在磁盘上并不是连接排列的,而是分散在硬盘的不同区域的,所以,进一步导致查询效率低下!
使用索引可以非常明显的提升查询效率!
如果需要手动创建索引,需要自行执行创建索引的SQL语句,其命令基本格式大致是:
CREATE INDEX index_name ON table_name (field_name);
例如:
CREATE INDEX idx_name ON mall_category (name);
提示:如果表中已经存在数据,数据量越大,创建索引的耗时就越久!
如果需要删除已经存在的索引,其命令基本格式大致是:
DROP INDEX index_name ON table_name;
在创建索引时,MySQL会将对应的字段的数据进行排序,并在索引中记录下每条数据的位置信息,所以,索引相当于“书的目录”,后续,当需要根据此字段查询数据时,会先翻“书的目录”,找出数据对应的“页码”,并直接翻到对应的“那一页”,就可以把数据找出来了!所以,使用索引后,查询效率会非常高!
索引的本质是一种B+Tree结构(是一种树型结构)的数据,在MySQL中,InnoDB存储引擎中页的大小是16KB,如果使用BIGINT类型的主键,每个主键需要占用8Byte,在B+Tree中的指针是4~8Byte,所以,每个指针与主键形成1个B+Tree中的节点,每个节点最多占用16Byte,每页最少可以存储1024个节点,深度为3的B+Tree最少可以存储1024 * 1024 * 1024个节点,大约是1000 * 1000 * 1000 = 1000000000个节点(10亿),所以,每个B+Tree可以维护约10亿个节点,即10亿个“内容与页码”的对应关系,如果表中的数据量不超过约10亿条,都只需要执行3次IO操作,就可以找出数据的位置。
在数据库中,即使你没有显式的创建索引,某个字段的查询效率可能也非常高,是因为索引有多种:
- PRIMARY KEY:主键索引
- UNIQUE:唯一索引
- INDEX:普通索引
- FULLTEXT:全文索引
基于索引的数据结构的特性,在使用时,必须注意:
- 索引不会包含有NULL值的列
- 数据量非常少的表没有必要创建索引,索引也需要维护,并占用一定的存储空间
- 数据经常变化的字段不要创建索引,因为,数据的变化可能需要同步更新索引,导致写数据的效率降低
- 查询时需要计算字段的值时,索引是无效的(不会发挥作用),例如:
where age / 10 > 8
时,age
列的索引就是无效的 - 左侧的模糊查询无法使用索引,因为索引是基于这一列的数据进行排序得到的,如果执行左侧模糊查询,则排序是无意义的,所有数据都需要被检查是否匹配
- 在开发实践中,几乎不使用模糊查询
除了以上限制以外,不同的企业可能有更高的要求:
- 类别为
text
的字段不允许使用索引 - 类别为
varchar
且字段值可能很长的字段不允许使用索引