mysql索引

MySQL中的索引

索引的作用: 索引就是帮助mysql高速的获取数据的一种数据结构,索引就像是一种书的目录一样

索引的类型

Hash: 查询时调用Hash函数获得地址,回表查询实际数据。(InnoDB和MylSAM不支持,Memory支持)。
B+树: 每次从根节点出发去查询,然后得到地址,回表查询实际数据。

二叉查找树、B树、B+树

二叉查找树(二叉排序树、二叉搜索树): 一个节点最多两个子节点(左小右大),查询次数和比较次数都是最小的,但是索引是存在磁盘的,当数据量过大的时候,不能直接把整个索引文件加载到内存,需要分多次IO,最坏的情况IO的次数就是树的高度,为了减少IO,需要把树从竖向变成横向。
B树( B- ): 是一种多路查询树,每个节点包含K个子节点,节点都存储索引值和数据,K是B树的阶(树高被称为树的阶)。虽然比较的次数比较多,但是是在内存的比较,可以忽略不计,但是B树IO的次数要比二叉查找树要少,因为B树的高度可以更低。
B+树: B树的升级版,只有叶子节点储存的是索引值指向的数据库的数据。

为什么使用B+树不用B树

  1. B树只适合随机检索,而B+树同时支持随机检索和顺序检索(因为叶子节点相当于链表,保存索引值都是有序的)。
    顺序检索: 按照序列顺序遍历比较找到给定值。
    随机检索: 不断从序列中随机抽取数据进行比较,最终找到结果。

  2. 减少了磁盘IO,提高空间利用率: 因为B+树非叶子节点不会存放数据,只有索引值,所以非叶子节点可以保存更多的索引值,这样B+树就可以更矮,减少IO次数。

  3. B+树适合范围查找: 这才是关键,因为数据库大部分都是范围查找,B+树的叶子节点是有序链表,直接遍历就行,而B树的范围查找可能两个节点距离很远,只能通过中序遍历去查找,所以使用B+树更合适。
    中序遍历: (根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面)

怎么避免索引失效

  • 某列使用范围查询(>、<、like、between and)时, 右边的所有列索引也会失效。
  • 不要对索引字段进行运算。
  • 在where子句中不要使用 OR、!=、<>和对值null的判断。
  • 避免使用’%'开头的like的模糊查询。
  • 字符串不加单引号,造成索引失效。

索引怎么设计

  • 选择唯一性索引:值是唯一的,查询的更快。

  • 经常作为查询条件的字段加索引。

  • 为经常需要排序、分组和联合操作的字段建立索引:order by、group by、union(联合)、distinct(去重)等。

  • 限制索引个数:索引数量多,需要的磁盘空间就越多,更新表时,对索引的重构和更新就很费劲。

  • 表数据少的不建议使用索引(百万级以内):数据过少,有可能查询的速度,比遍历索引的速度都快。

  • 删除不常用和不再使用的索引。

  • 用类型小的类型做索引:比如:int和BIGINT能用int就使用int。因为类型小,查询速度快和索引占用的空间更少。

  • 使用前缀索引,要是字符串越长,那么索引占的空间越大,并且比较起来就时间就越长。

使用索引的优点和缺点

优点:

  • 索引能够显著加速数据检索过程。通过直接定位到数据所在的位置,避免了全表扫描,尤其是在大型数据表中,查询性能提升尤为明显。

  • 对于包含ORDER BYGROUP BY子句的查询,如果排序或分组的列上有索引,数据库可以利用索引的预排序特性,减少甚至避免额外的排序操作,从而加快查询速度。

  • 唯一索引可以确保表中不会有重复的记录,这对于维护数据完整性非常重要,比如身份证号、邮箱地址等唯一标识字段。

  • 由于索引是对数据的排序引用,数据库在查找数据时可以更快地定位到具体磁盘块,减少了磁盘I/O操作次数,提升了整体效率。

  • 外键索引可以加强表间的参照完整性,确保在插入、更新或删除操作时,相关联的数据保持一致。

缺点:

  • 索引也是一个文件,所以会占用空间。
  • 降低更新的速度,因为不光要更新数据,还要更新索引。

索引的类型

1. 普通索引(Non-Unique Index)

普通索引是最基本的索引类型,没有任何唯一性约束。

创建SQL示例:

-- 在已存在的表上创建索引
CREATE INDEX idx_employee_name ON employees(name);

-- 在创建表的同时定义索引
CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    -- 这里定义了一个名为idx_employee_name的索引
    INDEX idx_employee_name (name)
);

注解: 这种索引可以加快基于name列的查询速度,但允许索引列中存在重复值。

2. 唯一索引(Unique Index)

唯一索引要求索引列的值必须唯一,但允许有多个NULL值(除非列定义为NOT NULL)。

创建SQL示例:

CREATE UNIQUE INDEX idx_employee_email ON employees(email);

注解: 确保email列中的值是唯一的,有助于快速定位记录,同时保持数据的唯一性约束。

3. 主键索引(Primary Key Index)

主键索引是特殊的唯一索引,不允许NULL值,并且每个表只能有一个主键。

创建SQL示例:

-- 在创建表时定义主键
CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255) UNIQUE
);

-- 或者在表创建后添加主键(不常见,因为通常主键在创建表时定义)
ALTER TABLE employees ADD PRIMARY KEY (id);

注解: 主键自动成为聚集索引,决定了表中数据的物理排列顺序。

4. 联合索引(Composite Index / Multi-Column Index)

联合索引是在多个列上创建的索引,优化涉及多个列的查询。

创建SQL示例:

CREATE INDEX idx_employee_name_email ON employees(name, email);

注解: 该索引对nameemail两列联合排序,查询时如果条件中包含了这两个列或它们的前缀,索引将最有效。

5. 全文索引(Full-Text Index)

全文索引适用于文本类型列的全文搜索。

创建SQL示例:

CREATE FULLTEXT INDEX idx_employee_bio ON employees(bio);

注解: 适用于bio列的大文本内容搜索,提高了复杂的文本搜索性能。

6. 空间索引(Spatial Index)

空间索引用于优化地理空间数据类型的查询,如点、线、面等。

创建SQL示例:

CREATE SPATIAL INDEX idx_employee_location ON employees(location);

注解: 当location列存储地理坐标或形状时,空间索引可以加速地理位置相关的查询。

7. 覆盖索引(Covering Index)

虽然不是独立的索引类型,但它是索引设计的一个概念,指的是索引包含了查询所需的所有列,使得MySQL可以直接从索引中获取数据而无需回表查询。

创建SQL示例:

-- 例如,如果经常执行以下查询,可以创建一个覆盖索引
SELECT name, email FROM employees WHERE age > 30;

-- 创建一个包含(name, email, age)的索引,使其成为覆盖索引
CREATE INDEX idx_employee_age_name_email ON employees(age, name, email);

注解: 通过包含查询中需要的所有列,覆盖索引可以显著提高查询性能,减少磁盘I/O。

请注意,选择合适的索引类型和设计时,需根据实际的数据分布、查询模式和性能需求来决定,以达到最佳的性能优化效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值