下面这条 SQL,你怎么通过索引来提高查询效率呢?
select * from order where status = 1 order by create_time asc
更优的方式是建立一个 status 和 create_time 组合索引,这是为了避免 MySQL 数据库发生文件排序。因为在查询时,你只能用到 status 的索引,但如果要对 create_time 排序,就要用文件排序 filesort,也就是在 SQL 执行计划中,Extra 列会出现 Using filesort。
利用索引的有序性,在 status 和 create_time 列建立联合索引,这样根据 status 筛选后的数据就是按照 create_time 排好序的,避免在文件排序。
InnoDB 是 MySQL 建表时默认的存储引擎,B+Tree 索引类型也是 MySQL 存储引擎采用最多的索引类型。
B+Tree 相比于 B 树和二叉树来说,最大的优势在于查询效率。
-
通过非主键(辅助索引)查询商品数据的过程
会先检索辅助索引中的 B+Tree 的 商品编码,找到对应的叶子节点,获取主键值,然后再通过主键索引中的 B+Tree 树查询到对应的叶子节点,然后获取整行数据。这个过程叫回表。
B+Tree 索引的优势
-
B+Tree 相对于 B 树 索引结构的优势
B+Tree 只在叶子节点存储数据,而 B 树 的非叶子节点也要存储数据,所以 B+Tree 的单个节点的数据量更小,在相同的磁盘 I/O 次数下,就能查询更多的节点。
B+Tree 叶子节点采用的是双链表连接,适合 MySQL 中常见的基于范围的顺序查找
-
B+Tree 相对于二叉树索引结构的优势
对于有 N 个叶子节点的 B+Tree,其搜索复杂度为O(logdN),其中 d 表示节点允许的最大子节点个数为 d 个。在实际的应用当中, d 值是大于100的,这样就保证了,即使数据达到千万级别时,B+Tree 的高度依然维持在 3~4 层左右,也就是说一次数据查询操作只需要做 3~4 次的磁盘 I/O 操作就能查询到目标数据
-
B+Tree 相对于 Hash 表存储结构的优势
Hash 表不适合做范围查询
通过执行计划查看索引使用详情
possible_keys 字段表示可能用到的索引,key 字段表示实际用的索引,key_len 表示索引的长度,rows 表示扫描的数据行数。
重点关注 type 字段
-
ALL(全表扫描);
-
index(全索引扫描);
-
range(索引范围扫描);
-
ref(非唯一索引扫描);
-
eq_ref(唯一索引扫描);
-
const(结果只有一条的主键或唯一索引扫描)。
索引失效的常见情况
-
索引列上做了计算、函数、类型转换操作,这些情况下索引失效是因为查询过程需要扫描整个索引并回表,代价高于直接全表扫描;
-
like 匹配使用了前缀匹配符 '%abc';
-
字符串不加引号导致类型转换
常见优化索引的方法
-
前缀索引优化,在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。前缀索引有一定的局限性,例如 order by 就无法使用前缀索引,无法把前缀索引用作覆盖索引。
-
覆盖索引优化,覆盖索引是指 SQL 中 query 的所有字段,在索引 B+tree 的叶子节点上都能找得到的那些索引,从辅助索引中查询得到记录,而不需要通过聚簇索引查询获得。
-
联合索引 联合索引时的字段顺序,对索引效率也有很大影响。越靠前的字段被用于索引过滤的概率越高,实际开发工作中建立联合索引时,要把区分度大的字段排在前面
标签:前缀,扫描,Tree,查询,索引,原理,优化,节点 From: https://www.cnblogs.com/jiaozg/p/17214780.html