博客
关于我
Mysql 索引问题集锦
阅读量:788 次
发布时间:2023-02-11

本文共 2446 字,大约阅读时间需要 8 分钟。

Mysql 中的索引

索引是数据库中用来加快查询速度的重要工具。它类似于数据结构中的键,用于快速定位和检索数据。Mysql中的索引分为多种类型,包括普通索引、唯一索引、主键索引以及全文索引等。以下是对这些索引类型的详细分析。

Mysql 索引的分类

从数据结构角度来看,Mysql中的索引主要包括以下几种:

  • B+树索引:这是Mysql中最常用的索引类型。B+树通过将键值按顺序存储在叶子节点实现高效查找。
  • 哈希索引:适用于单值查询场景,但在范围查询中效率较低。
  • FULLTEXT索引:专门用于全文检索的索引类型,支持文本片段的快速查找。
  • R-树索引:用于处理GIS(地理信息系统)数据,支持对空间数据进行高效的范围查询。
  • 从物理存储角度来看,Mysql中的索引主要分为两类:

  • 聚集索引(Clustered Index):将所有的数据行按照主键值顺序存储,这使得查询时可以直接通过主键找到对应的数据行。
  • 非聚集索引(Non-Clustered Index):只存储索引字段的值,不包含数据行地址,查询时需要结合主键或其他聚集索引进行定位。
  • 从逻辑角度来看,Mysql中的索引主要分为以下几种:

  • 主键索引:与表的主键字段一致,是唯一且不含空值的索引。
  • 唯一索引:与主键不同,允许空值,但同一表中不能有多个唯一索引。
  • 单列索引:仅对单一字段进行索引。
  • 多列索引(联合索引):同时对多个字段进行索引,可以显著提升复杂查询的效率。
  • 为什么 InnoDB 表最好要有自增列做主键?

    InnoDB引擎使用B+树存储数据,所有索引字段都会被存储在B+树的叶子节点中。为了确保查询效率,InnoDB会优先选择自增列(如INT或BIGINT类型)作为主键,因为这些字段的值通常是有序的,写入和查询时可以与B+树的叶子节点顺序保持一致。

    如果表中没有自增列可以作为主键,InnoDB会选择以下方式:

  • 如果存在可以作为唯一索引的字段(且不含NULL值),则将该索引作为主键。
  • 如果没有合适的唯一索引,InnoDB会自动为表生成一个ROWID字段,这是一个6字节的唯一递增值,用于作为隐含的聚集索引。
  • 选择自增列作为主键可以带来显著的性能优势。例如,自增列的插入操作会自然地按照顺序添加到B+树的叶子节点中,减少了索引页分裂和数据移动的开销,从而提高了插入效率。

    Myisam 下的非聚集索引

    在Mysql 5.5版本及之前,MyISAM引擎是默认数据库引擎之一。其索引结构与InnoDB有以下不同之处:

  • MyISAM的非聚集索引仅存储索引键值,不包含数据地址。
  • MyISAM引擎使用表锁机制,不支持事务和外键约束。
  • 非聚集索引的查询效率较低,因为这些索引不直接包含数据地址,查询时需要额外的步骤来定位数据。
  • 在MyISAM引擎中,主键索引是唯一的索引类型,且与数据记录紧密相关。查询时,主键索引会直接指向数据所在的页面。

    InnoDB 下的聚集索引

    InnoDB引擎从Mysql 5.5版本起成为默认引擎,它的聚集索引与MyISAM有显著不同:

  • InnoDB的聚集索引是表的主键,同时存储了数据行地址。
  • 非主键索引(辅助索引)仅存储索引键值,不包含数据地址。
  • InnoDB支持行锁机制,能够在高并发场景下提供更好的并发控制能力。
  • InnoDB引擎通过聚集索引实现了高效的数据检索。主键索引直接将数据行定位到B+树的叶子节点,而辅助索引则需要依赖主键索引来定位数据行。

    什么时候使用索引?

    在数据库设计中,合理使用索引可以显著提升查询效率。以下是一些建议:

  • 对于频繁查询的字段(如WHERE、GROUP BY、ORDER BY中的字段)建议创建索引。
  • 避免使用复杂的子查询,优先通过索引加快查询速度。
  • 适度限制查询结果集大小(如使用LIMIT),可以提高查询效率。
  • 合理设计表结构,减少跨表查询,常用数据和不常用数据分离存储。
  • 避免使用宽泛的查询(如LIKE "%name"),以防索引失效。
  • 减少在查询中使用函数,避免增加索引失效的可能性。
  • 尽量根据索引字段来检索数据,减少冗余计算。
  • 避免在核心业务中使用模糊查询(如LIKE "name%"),以防索引失效。
  • 添加索引

    在数据库设计阶段就要考虑索引的添加,正确的索引设计可以显著提升查询性能。以下是添加索引的几种方法:

  • 创建表时添加索引

    CREATE TABLE tb_name (    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    name CHAR(32) NOT NULL,    identify_num BIGINT NOT NULL UNIQUE,    INDEX name_index (name(32)));
  • 在表结构修改时添加索引

    ALTER TABLE tb_name ADD INDEX name_index (name(32));
  • 创建唯一索引

    CREATE UNIQUE INDEX identify_index ON tb_name (identify_num);
  • 索引失效

    索引的失效通常发生在以下场景:

  • 使用宽泛的LIKE操作

    -- 如下会导致索引失效:SELECT * FROM u1 WHERE name LIKE "%name%"-- 如下不会导致索引失效:SELECT * FROM u1 WHERE name LIKE "name%"
  • 字段值经过函数处理

    SELECT * FROM u1 WHERE md5(name) = 'j';
  • 联合索引中的字段顺序:将区分度较高的字段放在索引的前面可以提高查询效率,但如果字段顺序不合理,可能导致索引失效。

  • 通过以上分析,可以看出索引在数据库性能优化中的重要性。合理设计和使用索引,可以显著提升数据库的查询效率,减少锁竞争和数据读写开销。不过,在实际应用中,也需要注意索引的失效情况,避免因过度依赖索引而导致性能问题。

    转载地址:http://vbbfk.baihongyu.com/

    你可能感兴趣的文章
    9个常用ES6特性归纳(一般用这些就够了)
    查看>>
    3D渲染集群,你了解多少?
    查看>>
    华为云FusionInsight湖仓一体解决方案的前世今生
    查看>>
    C++调用Go方法的字符串传递问题及解决方案
    查看>>
    mysql zip安装
    查看>>
    Python 内置函数笔记
    查看>>
    BootStrapTable 错误
    查看>>
    代码整洁之道小结
    查看>>
    js new Date 创建时间默认是8点
    查看>>
    Python实现cmd命令连续执行
    查看>>
    罗马数字
    查看>>
    IO多路复用小故事
    查看>>
    纠错码简介
    查看>>
    码云 Pages 搭建
    查看>>
    《论可计算数及其在判定上的应用》简单理解
    查看>>
    中国剩余定理证明过程
    查看>>
    kafka告警简单方案
    查看>>
    java接口中多继承的问题
    查看>>
    java中Object.equals()简单用法
    查看>>
    一个小例子对多态简单的理解
    查看>>