InnoDB主键索引树和二级索引树

InnoDB主键索引树的结构

InnoDB存储引擎采用B+树作为主键索引的数据结构。主键索引的叶子节点存储完整的数据记录(即聚簇索引),而非叶子节点存储键值和指向子节点的指针。主键索引的B+树高度通常维持在3-4层,能有效支持千万级数据的高效查询。

-- 创建带有主键的表
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    age INT,
    email VARCHAR(100)
) ENGINE=InnoDB;

主键索引树的查找过程通过二分法快速定位数据。例如查询id=5的记录,从根节点开始比较键值,沿着指针逐层向下查找,直到定位到具体的叶子节点。

二级索引树的结构

二级索引(非聚簇索引)同样使用B+树结构,但其叶子节点存储的是主键值而非完整数据记录。查询时需要先通过二级索引找到主键,再回表查询主键索引获取完整数据。

-- 创建二级索引
CREATE INDEX idx_name ON users(name);

二级索引树的叶子节点按索引列排序,但存储的是主键值。例如name索引的叶子节点可能存储("Alice",1),("Bob",2)这样的键值对。当通过name查询时,先找到对应主键,再回表查询。

主键索引与二级索引的查询差异

主键索引查询可以直接获取完整数据:

-- 主键查询(不需要回表)
SELECT * FROM users WHERE id = 5;

二级索引查询需要回表操作:

-- 二级索引查询(需要回表)
SELECT * FROM users WHERE name = 'Alice';

性能差异体现在回表操作上。覆盖索引可以避免回表:

-- 覆盖索引查询(不需要回表)
SELECT id, name FROM users WHERE name = 'Alice';

索引维护操作

插入数据时,需要同时更新主键索引和所有二级索引:

-- 插入数据会更新所有索引
INSERT INTO users VALUES (10, 'Charlie', 25, 'charlie@example.com');

删除操作同样需要维护所有索引:

-- 删除数据会更新所有索引
DELETE FROM users WHERE id = 10;

更新操作如果涉及索引列,也需要更新相应索引:

-- 更新name会更新二级索引
UPDATE users SET name = 'David' WHERE id = 5;

复合索引的结构

复合索引也是B+树结构,键值按索引定义的列顺序组合:

-- 创建复合索引
CREATE INDEX idx_age_name ON users(age, name);

复合索引的叶子节点存储(age,name)组合和主键值。查询时可以充分利用最左前缀原则:

-- 能使用复合索引
SELECT * FROM users WHERE age = 25 AND name = 'Alice';

-- 也能使用复合索引(最左前缀)
SELECT * FROM users WHERE age = 25;

索引选择与优化

EXPLAIN命令可以分析查询使用的索引:

EXPLAIN SELECT * FROM users WHERE name = 'Alice';

强制使用特定索引:

SELECT * FROM users FORCE INDEX(idx_name) WHERE name = 'Alice';

索引选择性是优化的重要指标:

-- 计算索引选择性
SELECT COUNT(DISTINCT name)/COUNT(*) FROM users;

索引的物理存储

InnoDB索引存储在表空间文件中。可以通过INNODB_SYS_INDEXES视图查看索引元数据:

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES 
WHERE TABLE_ID = (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES 
WHERE NAME = 'test/users');

索引页的大小默认为16KB,可以通过参数调整:

[mysqld]
innodb_page_size=16K

索引分裂与合并

B+树在插入数据时会动态调整,发生页分裂:

-- 大量插入可能导致页分裂
INSERT INTO users SELECT * FROM large_users_table;

合并操作发生在删除大量数据后:

-- 删除大量数据后可能触发页合并
DELETE FROM users WHERE age > 60;

可以通过INNODB_METRICS监控索引分裂:

SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS 
WHERE NAME LIKE '%index_page%split%';

以上代码示例展示了InnoDB主键索引和二级索引的核心特性和操作方式,包括创建、查询、维护和优化等方面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值