mysql索引
首页 专栏 mysql 文章详情
0

mysql索引

诗富 发布于 3 月 9 日

索引的常见模型

哈希表
基于散列函数,不是有序的,而且散列冲突带来的链表结构等,会导致哈希索引做区间查询的速度很慢。因此这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。 有序数组
有序数组在等值查询和范围查询场景中的性能就都非常优秀,但是在需要 数据的时候就麻烦了,往中间插入一个记录就必须得挪动后面所有的记录,成本太高。只适用于静态存储引擎 搜索树
等值查询和范围查询性能都很好,且 数据也很方便,被广泛应用在数据库引擎中。

基于主键索引和普通索引的查询有什么区别?

如果语句是 select * from T where ID=500,即主键查询方式,则只需要搜索 ID 这棵 B+ 树; 如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

联合索引

假设,我们对(a,b)字段建立索引,那么入下图所示
他们是按照a来进行排序,在a相等的情况下,才按b来排序。

因此,我们可以看到a是有序的1,1,2,2,3,3。而b是一种全局无序,局部相对有序状态! 什么意思呢?

从全局来看,b的值为1,2,1,4,1,2,是无序的。

从局部来看,当a的值确定的时候,b是有序的。例如a = 1时,b值为1,2是有序的状态。当a=2时候,b的值为1,4也是有序状态。

最左前缀

根据联合索引分析,我们可以知道,联合索引跟顺序有关。因此,当执行a = 1 and b = 2是a,b字段能用到索引的。而执行a > 1 and b = 2时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这个范围内b值不是有序的,因此b字段用不上索引。这就是最左匹配原则,在遇到范围查询的时候,就会停止匹配。

以下是一些例子:
例1:建立索引(a,b,c)、(b,a,c)、(c,a,b)都可以,因为无范围查询,优化器会自动判断选择索引

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;

例2:建立索引(b,a)

SELECT * FROM table WHERE a > 1 and b = 2;

例3:(b,a)或者(b,c)都可以,要结合具体情况具体分析

SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3;

例4:对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序

SELECT * FROM `table` WHERE a = 1 ORDER BY b;

例5:(a,b,c)或(b,a,c)都可以

SELECT * FROM `table` WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;

例6:对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配,所以还是(a,b)

SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1;

覆盖索引

概念:如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作。explain extra列值为 using index

mysql 数据库 索引
阅读 30 发布于 3 月 9 日
收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar
诗富
2 声望
0 粉丝
关注作者
0 条评论
得票 时间
提交评论
avatar
诗富
2 声望
0 粉丝
关注作者
宣传栏
目录

索引的常见模型

哈希表
基于散列函数,不是有序的,而且散列冲突带来的链表结构等,会导致哈希索引做区间查询的速度很慢。因此这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。 有序数组
有序数组在等值查询和范围查询场景中的性能就都非常优秀,但是在需要 数据的时候就麻烦了,往中间插入一个记录就必须得挪动后面所有的记录,成本太高。只适用于静态存储引擎 搜索树
等值查询和范围查询性能都很好,且 数据也很方便,被广泛应用在数据库引擎中。

基于主键索引和普通索引的查询有什么区别?

如果语句是 select * from T where ID=500,即主键查询方式,则只需要搜索 ID 这棵 B+ 树; 如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

联合索引

假设,我们对(a,b)字段建立索引,那么入下图所示
他们是按照a来进行排序,在a相等的情况下,才按b来排序。

因此,我们可以看到a是有序的1,1,2,2,3,3。而b是一种全局无序,局部相对有序状态! 什么意思呢?

从全局来看,b的值为1,2,1,4,1,2,是无序的。

从局部来看,当a的值确定的时候,b是有序的。例如a = 1时,b值为1,2是有序的状态。当a=2时候,b的值为1,4也是有序状态。

最左前缀

根据联合索引分析,我们可以知道,联合索引跟顺序有关。因此,当执行a = 1 and b = 2是a,b字段能用到索引的。而执行a > 1 and b = 2时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这个范围内b值不是有序的,因此b字段用不上索引。这就是最左匹配原则,在遇到范围查询的时候,就会停止匹配。

以下是一些例子:
例1:建立索引(a,b,c)、(b,a,c)、(c,a,b)都可以,因为无范围查询,优化器会自动判断选择索引

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;

例2:建立索引(b,a)

SELECT * FROM table WHERE a > 1 and b = 2;

例3:(b,a)或者(b,c)都可以,要结合具体情况具体分析

SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3;

例4:对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序

SELECT * FROM `table` WHERE a = 1 ORDER BY b;

例5:(a,b,c)或(b,a,c)都可以

SELECT * FROM `table` WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;

例6:对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配,所以还是(a,b)

SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1;

覆盖索引

概念:如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作。explain extra列值为 using index