MySQL 三 索引

什么是索引?为什么要使用索引(优缺点)?

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。

索引的优点:

  • 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
  • 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

索引的缺点

  • 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
  • 空间方面:索引需要占物理空间。

索引有哪几种类型?

主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。

唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。

  • 可以通过 ALTER TABLE table_name ADD UNIQUE (column);创建唯一索引
  • 可以通过ALTER TABLE table_name ADD UNIQUE (column1,column2);创建唯一组合索引

普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。

  • 可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引

  • 可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引

全文索引:是目前搜索引擎使用的一种关键技术。

  • 可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引

索引的使用场景有哪些?

https://blog.csdn.net/u013400939/article/details/72869319

索引的基本原理

索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。

索引的原理很简单,就是把无序的数据变成有序的查询

  • 把创建了索引的列的内容进行排序

  • 对排序结果生成倒排表

  • 在倒排表内容上拼上数据地址链

  • 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据

索引的创建方式有哪几种?如何删除索引?

创建索引:

  • 在执行CREATE TABLE时创建索引

    CREATE TABLE user_index2 (
    id INT auto_increment PRIMARY KEY,
    first_name VARCHAR (16),
    last_name VARCHAR (16),
    id_card VARCHAR (18),
    information text,
    KEY name (first_name, last_name),
    FULLTEXT KEY (information),
    UNIQUE KEY (id_card)
    );
    
  • 使用ALTER TABLE命令去增加索引

    ALTER TABLE table_name ADD INDEX index_name (column_list);
    

    ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。

    其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。

    索引名index_name可自己命名,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。

  • 使用CREATE INDEX命令创建

    CREATE INDEX index_name ON table_name (column_list);
    

    CREATE INDEX可对表增加普通索引或UNIQUE索引。(但是,不能创建PRIMARY KEY索引

删除索引:

  • 根据索引名删除普通索引、唯一索引、全文索引,alter table 表名 drop KEY 索引名
    alter table user_index drop KEY name;
    alter table user_index drop KEY id_card;
    alter table user_index drop KEY information;
    
    删除主键索引:alter table 表名 drop primary key(因为主键只有一个)。这里值得注意的是,如果主键自增长,那么不能直接执行此操作(自增长依赖于主键索引)。
    需要先取消自增长,再进行删除。

主键索引与唯一索引的区别?

  1. 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。

  2. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。

  3. 唯一性索引列允许空值,而主键列不允许为空值。

  4. 主键列在创建时,已经默认为空值 ++ 唯一索引了。

  5. 一个表最多只能创建一个主键,但可以创建多个唯一索引。

  6. 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。

  7. 主键可以被其他表引用为外键,而唯一索引不能。

什么是覆盖索引?

覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。

聚集索引和辅助索引(非聚集索引)的区别?

https://www.jianshu.com/p/3cd3cec2e28c

索引的数据结构有哪些?

索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。

使用B+树的好处:

由于B+树的内部节点只存放键,不存放值,因此,一次读取,可以在内存页中获取更多的键,有利于更快地缩小查找范围。 B+树的叶节点由一条链相连,因此,当需要进行一次全数据遍历的时候,B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间

Hash索引和B+树有什么区别或者说优劣呢?

首先要知道Hash索引和B+树索引的底层实现原理:

hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。B+树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。
那么可以看出他们有以下的不同:
hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。
因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。
1. hash索引不支持使用索引进行排序,原理同上。
2. hash索引不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。
3. hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。
4. hash索引虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。

非聚簇索引一定会回表查询吗?

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。

举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。

索引设计的原则?

索引虽好,但也不是无限制的使用,最好符合一下几个原则:

  • 最左前缀匹配原则,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

  • 较频繁作为查询条件的字段才去创建索引

  • 更新频繁字段不适合创建索引

  • 若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)

  • 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

  • 定义有外键的数据列一定要建立索引。

  • 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

  • 对于定义为text、image和bit的数据类型的列不要建立索引。

使用索引一定能够提高查询的性能吗?

通常,通过索引查询数据比全表扫描要快。但是我们也必须注意到它的代价。

索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改。 这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O。 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。使用索引查询不一定能提高查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种情况:基于一个范围的检索,一般查询返回结果集小于表中记录数的30%;基于非唯一性索引的检索。

什么是最左前缀原则(最左匹配原则)?

  • 顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
  • 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
  • =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

B+树与B树?

https://segmentfault.com/a/1190000020416577

知道explain吗?说一说

要使用EXPLAIN,只需在查询中的SELECT关键字之前增加EXPLAIN这个词。MySQL会在查询上设置一个标记。当执行查询时,这个标记会使其返回关于在执行计划中每一步的信息,而不是执行它。它会返回一行或多行信息,显示出执行计划中的每一部分和执行的次序。

下面是一个可能的最简单的EXPLAIN结果。
在这里插入图片描述
在查询中每个表在输出中只有一行。如果查询是两个表的联接,那么输出中将有两行。别名表单算为一个表,因此,如果把一个表与自己联接,输出中也会有两行。“表”的意义在这里相当广:可以是一个子查询,一个UNION结果,等等。

MySQL EXPLAIN只能解释SELECT查询,并不会对存储程序调用和INSERT、UPDATE、DELETE或其他语句做解释。然而,你可以重写某些非SELECT查询以利用EXPLAIN。为了达到这个目的,只需要将该语句转化成一个等价的访问所有相同列的SELECT。任何提及的列都必须在SELECT列表,关联子句,或者WHERE子句中。

explain的更多使用信息:https://download.csdn.net/download/weixin_44533129/14820752

猜你喜欢

转载自blog.csdn.net/weixin_44533129/article/details/112846842