1、如果查询语句是
select <em> from table where ID = 100,以主键查询的方式,只需要搜索 ID 这棵 B+ 树。
2、如果查询语句是
select </em> from table where k = 1,以非主键的查询方式,则需要先搜索 k 索引树,得到 ID=100,再到 ID 索引树搜索一次,这个过程也被称为回表。 MySQL 中 B+ 树索引的管理
TABLE Testtable
ADD INDEX
idx_func_register_date((DATE_FORMAT(register_date,'%Y-%m')));
配合虚拟列(Generated Column)。
例如有如下表:
TABLE User (
userId BIGINT,
userInfo JSON,
mobile VARCHAR(255) AS (userInfo->>"$.mobile"),
PRIMARY KEY(userId),
UNIQUE KEY idx_mobile(mobile)
);
mobile 列就是一个虚拟列,由后面的函数表达式计算而成,本身这个列不占用任何的存储空间,而索引 idx_mobile 实质是一个函数索引。这样做的好处是在写 SQL 时可以直接使用这个虚拟列,而不用写冗长的函数:
-- 不用虚拟列
SELECT * FROM User
WHERE userInfo->>"$.mobile" = '15088888888'
-- 使用虚拟列
SELECT * FROM User
WHERE mobile = '15088888888'
最左前缀原则 B+ 树这种索引结构,可以利用索引的“最左前缀”,来定位记录。
例如我们有字段 a 和 b,都为高频字段,为了减少回表,我们可以建立联合索引 (a,b),这时不需要单独在 a 上建立索引了。
但是如果查询条件里面只有 b 的语句,是无法使用 (a,b) 这个联合索引的,这时候你不得不维护另外一个索引, 如果 a 字段比 b 字段大可以创建 (a,b)、(b) 这两个索引,反之创建 (b,a)、(a) 这两个索引。
上面的不同之处在性能差距上微乎其微。因为对于数据的读取不仅仅将需要读取的某一条数据从磁盘上读取出来,Innodb的数据是按照页为单位来进行读写的,每页的默认大小为16KB,所以对于普通索引来说,只是多做一次“查找和判断下一条记录”的操作,只需要一次指针寻找和一次计算,操作成本对于现在的 CPU 来说可以忽略不计。 更新时: