MySQL - 索引解释

46 阅读5分钟

什么是索引

索引是数据库中一个排序的数据结构,并用以协助快速查询、 更新数据库表中数据。

在MySQL中,索引分为FULLTEXT(全文索引)、NORMAL(默认类型)、SPATIAL(空间数据类型)、UNIQUE(唯一索引)这四种类型和BTREE(B-Tree平衡树)、HASH(哈希)两种方法。另外索引也分单列索引和组合索引,下面有解释。

(不过需要说明的是,索引虽然能在一定程度上加快数据检索效率,但也不是越多越好,因为索引会占用更多的磁盘空间,这点一定要注意,不然可能适得其反。)

索引类型如何选择


  • FULLTEXT(全文索引)

全文索引主要用于对文本内容进行关键字检索,支持关键字搜索、布尔搜索。

适用于需要对大量文本进行全文搜索的场景,例如文章、博客、新闻、论坛等包含大量文本内容的应用。

选择FULLTEXT索引时,需要考虑索引的列和表的字符集和排序规则,以确保适当的语言特性和搜索功能。

  • NORMAL(默认类型)

    NORAML也有人叫它普通索引或BTREE索引,是最常用的索引,按照排序顺序存储索引值,支持范围查询、排序和匹配查询。

    使

    适用于绝大多数的场景,不知道用什么索引的时候就用NORAML,特别是需要进行范围查询、排序和匹配查询的场景。

  • SPATIAL(空间数据类型)

    SPATIAL用于存储和查询具有空间属性的数据,例如地理位置数据或几何对象。支持空间操作,如点的包含关系、相交关系、距离计算等。

    适用于需要存储和处理地理位置数据或几何对象的应用,例如地图应用、位置服务、地理信息系统。

    如果你需要处理空间数据并进行空间操作,那么SPATIAL索引是必需的。使用SPATIAL索引可以加速空间查询操作

  • UNIQUE(唯一索引)

UNIQUE索引使用时需要区别数据字段内容在表内是绝对唯一的,如主键、身份证号、手机号这种。

适用于需要保证某个列或列组合的唯一性的场景,例如主键、唯一约束等

索引方法如何选择


上面确定了索引类型,现在来确定索引方法

  • HASH(哈希)

哈希方法只能适用于等值查询,如主键、身份证、手机号这种高度唯一性的数据用哈希会更比BTREE更快,但是,如果要进行数据排序,范围查询这种效率就不如BTREE了


  • BTREE(B-Tree)

B-Tree索引方法适用于绝大数查询场景,如果哈希满足不了你的需求时选B-Tree就对了。


单列索引还是组合索引


****通常一个索引只会包含一个数据列,除非你的SQL检索条件中会频繁包含多个固定的列时才适用于组合索引

索引的优缺点

  • 优点:

    1):索引减小了服务器需要扫描的数据量
    (2):索引可以帮助服务器避免排序和临时表
    (3):索引可以将随机I/O变成顺序I/O
    
  • 缺点:

    1):索引虽然会加快SQL读语句的效率,但同时会降低写语句的执行效率,包括UPDATEDELETEINSERT,因为更新表时,MySQL不仅要保存数据,还要保存索引文件
    (2):对于非常小的表,大部分情况下简单的全表扫描更高效
    (3):如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果
    (4):索引文件会占用更多的磁盘空间
    

为什么innodb要选择B+Tree而不是B-Tree

mysql数据结构演化过程:二叉排序树 → 二叉平衡树 → B-Tree(B树) → B+Tree(B+树)

B+树更适合外部存储(一般指磁盘存储),由于内节点(非叶子节点)不存储data,所以一个节点可以存储更多的内节点,每个节点能索引的范围更大更精确。也就是说使用B+树单次磁盘I/O的信息量相比较B树更大,I/O效率更高。

mysql是关系型数据库,经常会按照区间来访问某个索引列,B+树的叶子节点间按顺序建立了链指针,加强了区间访问性,所以B+树对索引列上的区间范围查询很友好。而B树每个节点的key和data在一起,无法进行区间查找

为什么查询语句没有命中索引

  • 组合索引不满足最左匹配原则
  • 使用了select *

    mysql> select * from table key = xxx;
    
  • 索引列参与了数学运算

    mysql> select * from table where id = 2 - 1;
    
  • 索引列参使用了某些内置函数

    mysql> select xxx from table where substr(xxx, 11, 4) = date_format(now(), '%m%d');
    
  • 错误的like语句

    mysql> select * from table where xxx like '%xxx%';
    
  • 索引字段传参时错误

如索引字段类型为varchar,调用时传入了int,反之亦然

  • 错误的使用or,>,<,>=,<=

    mysql> select xxx from table where id = 1 or xxx = "xxx";
    

    示例中如果xxx字段没有添加索引会导致id主键/其他索引失效

  • is not null,not in,not exists操作导致索引失效