MySQL 索引

一、什么是 MySQL 索引

MySQL 索引类似于书籍的目录,是数据库表中对一列或多列的值进行排序后形成的一种数据结构。它就像一个指引,能让数据库系统快速定位到表中特定的数据行,而不必扫描整个表。索引通常以 B 树或 B + 树的形式存储,与表中的数据相互关联,通过索引,数据库可以直接找到数据所在的物理位置,从而大大加快查询速度。

二、索引的作用

  1. 提高查询速度:这是索引最主要的作用。在一个拥有大量数据的表中,如果没有索引,查询操作可能需要逐行扫描整个表,这会耗费大量的时间。而有了索引,数据库可以通过索引快速定位到符合条件的数据,大幅缩短查询时间。例如,在一个包含百万条用户记录的表中,要查询某个特定用户名的用户信息,有索引时可能瞬间就能完成,没有索引则可能需要几秒甚至更长时间。
  2. 减少服务器扫描的数据量:索引可以帮助数据库服务器只扫描少量的数据就能找到目标信息,避免了对整个表的扫描,减轻了服务器的负担。

三、索引的类型

  1. 主键索引:它是一种特殊的唯一索引,不允许有空值。通常在创建表的时候指定,每个表只能有一个主键索引。例如,在创建用户表时,将用户 ID 设为主键,这样可以唯一标识每个用户,并且通过用户 ID 查询用户信息时会非常高效。
  2. 唯一索引:要求索引列的值必须唯一,但允许有空值。它可以保证数据的唯一性,防止重复数据的插入。比如,在用户表中对邮箱列创建唯一索引,就可以避免出现两个相同的邮箱地址。
  3. 普通索引:这是最基本的索引,没有任何限制,允许索引列的值重复和为空。它主要用于提高查询效率,适用于那些经常出现在查询条件中的列。
  4. 联合索引:由多个列组合而成的索引,遵循最左前缀原则。也就是说,在查询时,只有当查询条件中包含联合索引的最左列时,索引才可能被使用。例如,创建了(name, age)的联合索引,那么查询条件为 name=' 张三 ' 或者 name=' 张三 ' and age=20 时,索引可能会生效;但如果查询条件只是 age=20,那么该联合索引不会被使用。
  5. 全文索引:主要用于对文本内容进行全文检索,适用于 CHAR、VARCHAR、TEXT 等类型的列。它可以快速找到包含特定关键词的文本数据,比使用 like 进行模糊查询效率高很多。

四、创建和删除索引的方法

  1. 创建索引
  • 使用 CREATE INDEX 语句创建普通索引:CREATE INDEX index_name ON table_name (column_name);,其中 index_name 是索引的名称,table_name 是表名,column_name 是要创建索引的列名。
  • 使用 ALTER TABLE 语句添加索引:ALTER TABLE table_name ADD INDEX index_name (column_name);,这种方式也可以创建普通索引。对于主键索引,可以使用ALTER TABLE table_name ADD PRIMARY KEY (column_name);。对于唯一索引,使用ALTER TABLE table_name ADD UNIQUE index_name (column_name);。
  1. 删除索引
  • 使用 DROP INDEX 语句:DROP INDEX index_name ON table_name;,可以删除指定表中的指定索引。
  • 使用 ALTER TABLE 语句:ALTER TABLE table_name DROP INDEX index_name;,同样可以删除索引。如果要删除主键索引,使用ALTER TABLE table_name DROP PRIMARY KEY;。

一般来说,在经常用于查询条件的列、经常进行连接的列、经常出现在 ORDER BY 或 GROUP BY 子句中的列上适合创建索引。

五、索引的优缺点

1.优点

  • 显著提高查询效率,这是索引最核心的优势。
  • 可以保证数据的唯一性,如唯一索引和主键索引。
    2.缺点
  • 占用额外的存储空间:索引需要单独存储,会增加数据库的存储空间开销。
  • 降低数据更新速度:当对表中的数据进行插入、更新和删除操作时,数据库不仅要更新数据本身,还要维护索引结构,这会使这些操作的速度变慢。

六、使用索引的注意事项

  1. 不要在经常更新的列上创建过多索引:因为频繁的更新操作会导致索引频繁维护,影响性能。
  2. 不要在值很少的列上创建索引:比如一个列只有 "是" 和 "否" 两个值,创建索引对查询效率的提升不明显,反而会浪费存储空间。
  3. 查询时避免使用导致索引失效的操作:如在索引列上使用函数、不等于(!=、<>)、模糊查询的 % 在开头(如 '% abc')等,这些操作可能会使索引无法被使用,导致数据库进行全表扫描。
相关推荐
酷ku的森32 分钟前
Redis中的Zset数据类型
数据库·redis·缓存
zhong liu bin34 分钟前
MySQL数据库面试题整理
数据结构·数据库·mysql
luckys.one5 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
言之。7 小时前
Django中的软删除
数据库·django·sqlite
阿里嘎多哈基米8 小时前
SQL 层面行转列
数据库·sql·状态模式·mapper·行转列
抠脚学代码8 小时前
Ubuntu Qt x64平台搭建 arm64 编译套件
数据库·qt·ubuntu
jakeswang9 小时前
全解MySQL之死锁问题分析、事务隔离与锁机制的底层原理剖析
数据库·mysql
Heliotrope_Sun9 小时前
Redis
数据库·redis·缓存
一成码农9 小时前
MySQL问题7
数据库·mysql
吃饭最爱9 小时前
JUnit技术的核心和用法
数据库·oracle·sqlserver