mysql,简单介绍一下索引

本文深入探讨数据库索引的重要性,解释了索引如何帮助提高数据检索效率。文章详细介绍了索引的种类,包括单值索引、唯一索引和复合索引,并提供了实际应用案例。同时,文中还讨论了创建索引的策略,以及在特定情况下索引可能失效的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汉字很多,人力有时尽,人不可能记住所有的字,为了解决这个问题,于是有了字典。数据库里的数据很多,为了方便检索,于是有了索引。

索引,是一种数据结构,在这种数据结构中实现了高级的查找算法,索引可以帮助我们高效地获取数据,提高查询效率。

 

既然索引有这样的好处,那我们是不是每个字段都该建立索引呢?

当然是不,物极必反,索引是需要占用空间的,而且索引本身也不小,不能存储在内存空间,是存放在磁盘中的。

如果每个字段都建立索引,后果可想而知。

 

讨论索引的时候,如果没有特别的指明类型,一般都是B树索引。BTree索引可以查阅相关资料了解下,不赘述了。

除了B树索引,另外还有哈希索引等。

 

索引有哪些分类?

1.单值索引

单值索引是指一个索引只包含一个字段,一个表可以创建多个单值索引,但也不宜过多。

2.唯一索引

主键创建后一定包含一个唯一索引;但唯一索引不一定是主键,允许有空值,一个表可以创建多个唯一索引。

3.复合索引

因为一个查询一次至多只能使用一个索引,所以,如果都使用单值索引,在数据量较大的情况下,不能很好的区分数据,
于是引入了复合索引。

需要注意的是:复合索引是有顺序的! 举例说明一下。


例如,user表里有id,name,sex三个字段,并且我们创建了name+sex的复合字段。
select * from user where name=x and sex=x;
这个情况是允许使用上面的复合索引的。

select * from user where name=x;
这个情况也是允许使用上面的复合索引的。

select * from user where sex=x and name=x;
这种情况不允许使用,复合索引有顺序就是指这个意思。

select * from user where sex=x;
这种情况也不允许使用索引哦。
复合索引是遵循向左原则的,只要在查询的时候,是按照复合索引从左到右的顺序依次查询
不管查询条件是否完全满足所有的符合索引的列,都可以使用部分的符合索引;

 

选择哪些列创建索引?

1.查询较为频繁的字段应该创建索引;
2.唯一性太差的字段不应该创建索引,就算这个字段经常作为查询条件;
3.更新频繁的字段不应该创建索引,索引是需要维护成本的;
4.有where条件时才会走索引,所以如果这个列不会作为where的查询条件,没有必要为这个字段创建索引;
 

不走索引的情况

在以前的工作中,有一次发现在特殊的情况下,即使你创建了索引,并且也在where加上了索引条件,查询过程中还是没有走索引。例如:
1.使用不等于(!= 或者<>)的时候MySQL 无法使用索引
2.like 后面的字符当首位为通配符时不走索引;如
   like "北%",这种情况是走索引的
   like "%北",这种情况是不走索引的
3.索引字段 is null 不走索引;
4.索引字段前加了函数或参加了运算不走索引;
 

 

转载于:https://www.cnblogs.com/tinyj/p/9861109.html

<think>好的,我现在要介绍一下MySQL索引。首先,我需要确认用户已经了解数据库的基本概念,比如表、行、列,以及查询的基本操作。用户之前询问过脏读、幻读等问题,可能对数据库的并发控制有一定了解,但索引是另一个重要的话题。 接下来,我需要明确索引的定义和作用。索引是什么?简单来说,索引是帮助MySQL高效获取数据的数据结构,类似于书籍的目录。没有索引的话,数据库可能需要进行全表扫描,效率低下。 然后,需要介绍索引的类型。常见的索引类型包括B-Tree索引、哈希索引、全文索引等。其中,B-Tree索引MySQL中最常用的,适用于大部分场景。哈希索引则适用于等值查询,但不支持范围查询。全文索引用于文本搜索,比如MATCH AGAINST语句。 接下来要讲索引数据结构,比如B+树的结构和优势。B+树是一种平衡多路搜索树,适合磁盘存储,能够减少IO次数。叶子节点存储数据,并且有指针连接,方便范围查询。 然后,需要说明索引的分类。主键索引、唯一索引、普通索引、联合索引等。主键索引是唯一的,不允许NULL值;唯一索引要求列值唯一,但允许NULL;普通索引则没有这些限制。联合索引指的是多个列组合的索引,需要注意最左前缀原则。 还要提到覆盖索引的概念,即查询的列都在索引中,无需回表,提高效率。以及索引下推(Index Condition Pushdown, ICP),这是MySQL 5.6之后的优化,可以在索引层面过滤数据,减少回表次数。 然后,需要讨论索引的优点和缺点。优点包括加快查询速度,特别是WHERE、JOIN、ORDER BY等操作。缺点则是占用存储空间,降低写操作(INSERT、UPDATE、DELETE)的速度,因为索引需要维护。 接下来,可能需要讲解如何创建索引,比如使用CREATE INDEX语句,或者在创建表时指定。同时,要给出一些最佳实践,比如选择合适的列作为索引(高选择性、频繁查询的列),避免过度索引,以及如何分析索引的使用情况(EXPLAIN命令)。 还需要注意索引失效的情况,比如使用函数、类型转换、OR条件、前导通配符LIKE查询等,这些可能导致索引无法使用,需要全表扫描。 最后,可能需要对比不同存储引擎的索引实现,比如InnoDB和MyISAM的区别。InnoDB使用聚簇索引,数据存储在叶子节点,而MyISAM是非聚簇索引,数据和索引分开存储。 在思考过程中,可能会遗漏一些细节,比如全文索引的具体使用场景,或者空间索引介绍。另外,关于索引的维护,比如碎片整理、统计信息更新等,也可能需要提及。 需要确保解释清晰,避免术语混淆,比如B树和B+树的区别,或者覆盖索引和复合索引的不同。同时,结合实例说明会更易于理解,比如创建联合索引的例子,以及如何通过EXPLAIN分析查询计划。 可能还需要提到自适应哈希索引(Adaptive Hash Index)在InnoDB中的使用,这是MySQL自动为频繁访问的索引页创建的哈希索引,以加速查询。 总结时,要强调合理使用索引的重要性,根据实际查询需求设计合适的索引结构,平衡读写性能,并通过监控和优化工具持续调整。</think>### **MySQL 索引详解** #### **1. 索引的作用** 索引数据库中**快速查找数据**的数据结构,类似于书籍的目录。它通过减少磁盘 I/O 次数,显著提升查询效率,尤其是在大数据量场景下。 --- #### **2. 索引类型** | **类型** | **说明** | **适用场景** | |------------------|-------------------------------------------------------------------------|---------------------------| | **B+Tree 索引** | MySQL 默认索引结构,支持范围查询、排序、模糊匹配(如 `LIKE 'abc%'`) | 大多数场景(如主键、普通索引) | | **哈希索引** | 基于哈希表,仅支持等值查询(`=`),不支持排序或范围查询 | 内存表(如 MEMORY 引擎) | | **全文索引** | 对文本内容分词索引,支持自然语言搜索(`MATCH ... AGAINST`) | 大文本字段的搜索(如文章、日志) | | **空间索引** | 支持地理空间数据类型(如 `GEOMETRY`) | GIS 系统、地理位置查询 | --- #### **3. 索引分类** | **分类** | **特点** | |------------------|-------------------------------------------------------------------------| | **主键索引** | 唯一标识每行,不允许 `NULL`,表只能有一个主键索引(`PRIMARY KEY`) | | **唯一索引** | 确保列值唯一,允许 `NULL`(但只能有一个 `NULL`),可存在多个唯一索引(`UNIQUE`) | | **普通索引** | 无唯一性约束,仅加速查询(`INDEX` 或 `KEY`) | | **联合索引** | 多列组合的索引,需遵循**最左前缀原则**(如 `INDEX (a, b, c)`) | --- #### **4. B+Tree 索引结构** - **特点**: - 平衡多叉树,所有数据存储在叶子节点,非叶子节点仅存储键值。 - 叶子节点通过指针连接,支持高效的范围查询(如 `WHERE id > 100`)。 - **InnoDB 的聚簇索引**: - 主键索引的叶子节点直接存储行数据,因此**主键查询极快**。 - 若未定义主键,InnoDB 会自动生成隐藏的聚簇索引。 --- #### **5. 索引优化策略** - **覆盖索引**:查询的字段全部包含在索引中,无需回表(`EXPLAIN` 的 `Extra` 列显示 `Using index`)。 ```sql -- 假设有联合索引 (name, age) SELECT age FROM users WHERE name = '张三'; -- 覆盖索引 ``` - **索引下推(ICP)**:在存储引擎层过滤数据,减少回表次数(MySQL 5.6+ 支持)。 - **最左前缀原则**:联合索引按列顺序生效,如 `(a, b, c)` 支持 `a`, `a AND b`, `a AND b AND c`,但不支持 `b` 或 `c` 单独使用。 - **前缀索引**:对长文本字段(如 `VARCHAR(200)`)的前 N 个字符建索引,节省空间。 ```sql CREATE INDEX idx_email_prefix ON users(email(10)); -- 取前10个字符 ``` --- #### **6. 索引失效场景** 以下操作可能导致索引失效,触发全表扫描: - **对索引列使用函数或计算**: ```sql SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 失效 ``` - **类型转换**(如字符串列用数字查询): ```sql SELECT * FROM users WHERE id = '100'; -- 若 id 是 INT,会隐式转换导致失效 ``` - **前导通配符 `LIKE`**: ```sql SELECT * FROM users WHERE name LIKE '%abc%'; -- 无法使用索引 ``` - **OR 条件包含非索引列**: ```sql SELECT * FROM users WHERE age = 20 OR address = '北京'; -- 若 address 无索引,整体失效 ``` --- #### **7. 索引管理** - **创建索引**: ```sql CREATE INDEX idx_name ON users(name); -- 普通索引 ALTER TABLE users ADD UNIQUE (email); -- 唯一索引 ``` - **删除索引**: ```sql DROP INDEX idx_name ON users; ``` - **查看索引**: ```sql SHOW INDEX FROM users; ``` --- #### **8. 索引的优缺点** | **优点** | **缺点** | |----------------------------|-----------------------------| | 加速查询(WHERE、JOIN、ORDER BY) | 占用额外磁盘空间 | | 减少服务器排序和临时表的使用 | 降低写操作性能(需维护索引) | | 加速表连接操作 | 不合理的索引设计会拖慢查询 | --- #### **9. 最佳实践** 1. **选择性高的列建索引**:区分度高的列(如用户 ID)比性别更适合索引2. **避免冗余索引**:联合索引 `(a, b)` 可替代单独的 `a` 索引。 3. **监控索引使用**:通过 `SHOW INDEX_STATISTICS` 或 `INFORMATION_SCHEMA` 分析索引利用率。 4. **定期优化表**:重建索引减少碎片(`OPTIMIZE TABLE users`)。 --- #### **10. 示例:EXPLAIN 分析查询** ```sql EXPLAIN SELECT * FROM users WHERE name = 'Alice' AND age > 20; ``` - **结果字段**: - `type`:访问类型(`ref` 表示索引查找,`ALL` 表示全表扫描)。 - `key`:实际使用的索引。 - `rows`:预估扫描行数。 - `Extra`:额外信息(如 `Using where`, `Using index`)。 --- **总结**:索引数据库性能优化的核心手段之一,需根据业务查询模式合理设计,兼顾查询效率写入成本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值