深入理解数据库中的聚集索引与非聚集索引

🌈 我是“没事学AI”, 欢迎咨询、交流,共同学习:
👁️ 【关注】我们一起挖 AI 的各种门道,看看它还有多少新奇玩法等着咱们发现
👍 【点赞】为这些有用的 AI 知识鼓鼓掌,让更多人知道学 AI 也能这么轻松
🔖 【收藏】把这些 AI 小技巧存起来,啥时候想练手了,翻出来就能用
💬 【评论】说说你学 AI 时的想法和疑问,让大家的思路碰出更多火花
👉 关注获取更多AI技术干货,点赞/收藏备用,欢迎评论区交流学习心得! 🚀

一、索引的基本概念

索引是数据库中用于提高查询效率的数据结构,通过创建索引可以大幅减少数据扫描的范围,加快查询速度。在关系型数据库中,索引主要分为聚集索引(Clustered Index)和非聚集索引(Non-Clustered Index)两种类型,它们在数据存储方式和应用场景上存在显著差异。

二、聚集索引

2.1 定义与特性

聚集索引决定了表中数据的物理存储顺序,即数据行的物理顺序与索引的逻辑顺序一致。一个表只能有一个聚集索引,因为数据的物理存储顺序只有一种。

聚集索引的特性:

  • 数据与索引结构存储在一起
  • 叶子节点直接包含数据行
  • 插入新数据可能导致数据物理位置移动
  • 对范围查询和排序操作效率高

2.2 适用场景

  • 经常需要按范围查询的列(如时间范围、数值范围)
  • 频繁进行排序的列
  • 表中存在明显的查询热点列

2.3 案例实现

以MySQL中的InnoDB存储引擎为例,创建一个包含聚集索引的表:

-- 创建以id为主键(默认创建聚集索引)的用户表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE,
    created_at DATETIME NOT NULL
);

-- 插入测试数据
INSERT INTO users (username, email, created_at) VALUES
('user1', 'user1@example.com', '2023-01-01 08:00:00'),
('user2', 'user2@example.com', '2023-01-02 09:00:00'),
('user3', 'user3@example.com', '2023-01-03 10:00:00');

-- 按主键范围查询(利用聚集索引,效率高)
SELECT * FROM users WHERE id BETWEEN 1 AND 100;

在InnoDB中,主键默认作为聚集索引,如果表中没有定义主键,InnoDB会选择一个唯一的非空索引代替;如果没有这样的索引,InnoDB会隐式创建一个虚拟的聚集索引。

三、非聚集索引

3.1 定义与特性

非聚集索引的索引结构与数据的物理存储顺序无关,索引的叶子节点存储的是索引键值和指向对应数据行的指针(或主键值)。一个表可以有多个非聚集索引。

非聚集索引的特性:

  • 索引结构与数据分开存储
  • 叶子节点不直接包含数据行
  • 插入新数据不会改变数据的物理存储顺序
  • 索引维护成本相对较低

3.2 适用场景

  • 经常作为查询条件的非主键列
  • 需要频繁进行精确匹配查询的列
  • 不适合创建聚集索引但查询频繁的列

3.3 案例实现

继续使用上面的users表,创建非聚集索引并演示查询:

-- 为email列创建非聚集索引
CREATE INDEX idx_users_email ON users(email);

-- 为created_at列创建非聚集索引
CREATE INDEX idx_users_created_at ON users(created_at);

-- 使用email索引进行查询
SELECT * FROM users WHERE email = 'user2@example.com';

-- 使用created_at索引进行查询
SELECT username, email FROM users WHERE created_at > '2023-01-02 00:00:00';

上述查询会先通过非聚集索引找到对应的数据行指针,再通过指针定位到具体的数据行(这个过程称为"书签查找")。

四、聚集索引与非聚集索引的区别

特性聚集索引非聚集索引
数量限制一个表只能有一个一个表可以有多个
数据存储索引与数据存储在一起索引与数据分开存储
物理顺序决定数据的物理存储顺序不影响数据的物理存储顺序
叶子节点包含完整的数据行包含索引键值和数据行指针
插入操作可能导致大量数据移动不会导致数据物理移动
查询效率范围查询效率高精确匹配查询效率高

五、索引使用的最佳实践

5.1 索引设计原则

  1. 为经常作为查询条件、排序和分组的列创建索引
  2. 避免在频繁更新的列上创建过多索引
  3. 对于小表,索引可能不会提高性能,甚至会降低性能
  4. 考虑索引选择性(区分度),选择性高的列更适合创建索引

5.2 实际应用示例

-- 不恰当的索引使用
CREATE INDEX idx_users_username ON users(username); -- 如果username区分度低,不适合建索引

-- 合理的复合索引创建(遵循最左前缀原则)
CREATE INDEX idx_users_created_at_username ON users(created_at, username);

-- 有效利用复合索引的查询
SELECT * FROM users WHERE created_at > '2023-01-01' AND username LIKE 'user%';

5.3 索引维护

-- 查看索引使用情况
SHOW INDEX FROM users;

-- 分析索引效率
EXPLAIN SELECT * FROM users WHERE email = 'user2@example.com';

-- 删除不再使用的索引
DROP INDEX idx_users_email ON users;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没事学AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值