MySQL调优学习笔记(三):组合索引和函数索引

本文详细探讨了组合索引如何通过覆盖查询和避免排序提升性能,以及函数索引如何优化函数表达式查询,包括其在虚拟列和SQL规范的应用。了解这两种技术对于优化数据库查询至关重要。

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

目录

什么是组合索引

组合索引的优势

什么是函数索引

函数索引的优势

总结

参考资料:姜承尧的MySQL实战宝典

什么是组合索引

组合索引是指由多个列所组合而成的B+树索引,组合索引既可以是主键索引,也可以是二级索引。
组合索引(a,b)和组合索引(b,a)排序结果是完全不一样的。对组合索引(a,b)来说,它可以对以下几个查询进行优化。

SELECT * FROM table_name WHERE a = ?

SELECT * FROM table_name WHERE a = ? AND b = ?

SELECT * FROM table_name WHERE b = ? AND a = ?

SELECT * FROM table_name WHERE a = ? ORDER BY b DESC

然而组合索引(a,b)无法对以下几个查询进行优化,因为(a,b)排序并不能推出(b,a)排序。

SELECT * FROM table_name WHERE b = ?

SELECT * FROM table_name WHERE b = ? ORDER BY a DESC

组合索引的优势

1. 覆盖多个条件
组合索引是针对多个列的索引,可以提升多列查询的性能。

2. 避免额外排序
设计组合索引(a,b)可以避免额外排序,提升WHERE a = ? ORDER BY b 的查询性能。

3. 避免回表
由于二级索引的叶子节点,包含索引键值和主键值,若查询的字段在二级索引的叶子节点中,则可直接返回结果,无需回表,提升性能。这种通过组合索引避免回表的优化技术也称为索引覆盖。

什么是函数索引

从 MySQL 5.7 版本开始,就开始支持创建函数索引,即索引键是一个函数表达式。

函数索引的优势

1. 优化SQL查询性能
索引 idx_register_date 只对 register_date排序,没有对DATE_FORMAT(register_date,'%Y-%m')排序,因此代码处第2条SQL无法使用二级索引idx_register_date。

索引idx_func_register_date对DATE_FORMAT(register_date,'%Y-%m')排序,因此代码处第4条SQL可以使用二级索引idx_func_register_date。

数据库规范要求查询条件中函数写在等式右边,而不能写在左边,也是这个原因。

#对register_date列创建索引idx_register_date
ALTER TABLE user 
ADD INDEX idx_register_date(register_date);

#查询时无法使用索引idx_register_date
SELECT * FROM user
WHERE DATE_FORMAT(register_date,'%Y-%m')='2020-01';

#对register_date列创建函数索引idx_func_register_date
ALTER TABLE user 
ADD INDEX idx_func_register_date((DATE_FORMAT(register_date,'%Y-%m')));

#查询时使用索引idx_func_register_date
SELECT * FROM user
WHERE DATE_FORMAT(register_date,'%Y-%m')='2020-01';

2. 配合虚拟列使用

列 cellphone 是一个虚拟列,它是由后面的函数表达式计算而成,不占用任何的存储空间,而索引 idx_cellphone 对虚拟列排序,实质上是一个函数索引。这样做的好处是在写 SQL 时都可以直接使用这个虚拟列,而不用写冗长的函数。

CREATE TABLE userLogin (
    userId BIGINT,
    loginInfo JSON,
    cellphone VARCHAR(255) AS (loginInfo->>"$.cellphone"),
    PRIMARY KEY(userId),
    UNIQUE KEY idx_cellphone(cellphone)
);
#不使用虚拟列进行查询
SELECT * FROM userLogin
WHERE loginInfo->>"$.cellphone" = '11111111111'

#使用虚拟列进行查询
SELECT * FROM userLogin
WHERE cellphone = '11111111111'

总结

  • 组合索引也是一颗B+树,只是索引由多个列组成,组合索引既可以是主键索引,也可以是二级索引;
  • 组合索引的优势:覆盖多个查询条件;避免额外排序;可以实现索引覆盖技术,避免回表;
  • 函数索引,即索引键是一个函数表达式;
  • 函数索引的优势:有时可通过函数索引快速解决SQL的性能问题;在虚拟列上创建索引本质就是函数索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值