最佳左前缀法则(Optimal Left-Prefix Rule)

一、举例

表A有索引index (a,b,c)有三个字段,

select * from A where c = '1' ,不会走index索引;

select * from A where b =‘1’ and c ='2' 也不会走index索引;

select * from A where a=‘0’ and b='1' ,索引部分生效;

select * from A where a=‘0’ and b='1'  and c='2',索引生效。

二、定义与原理

        最佳左前缀法则指的是在创建和使用复合索引时,查询条件应该尽量包含从索引最左边开始的一个或多个连续列。换句话说,如果一个复合索引是按照列A, 列B, 列C的顺序创建的,那么最优的查询将包括列A(单独使用或与其他列组合),其次是列A和列B的组合,最后是列A、列B和列C的组合。如果查询只涉及列B或列C而不包括前面的列A,则无法有效利用该复合索引。

        这一原则背后的逻辑在于B树(或其他类似的平衡树结构)索引的工作原理:它们按照索引键的顺序组织数据,而复合索引的键是由多个列组成的。因此,只有当查询能够匹配到索引的最左侧部分时,数据库引擎才能有效地遍历索引树来查找匹配的记录。

三、特殊情况

        select * from A where c='2' and b='1' and a=‘0’ 会走索引吗?

        会走索引,且能充分利用该联合索引。

原因分析:

        1.联合索引的本质
        联合索引 (a, b, c) 是按 a→b→c 的顺序构建的 B+ 树,索引节点先按 a 排序,相同 a 再按 b 排序,相同 b 最后按 c 排序。

        2.查询条件的适配性
        虽然查询条件中 c、b、a 的顺序与索引定义的 a、b、c 不同,但 MySQL 优化器会自动调整 WHERE 子句中 AND 连接的条件顺序,使其与索引的字段顺序匹配(因为 AND 条件的逻辑顺序不影响结果)。
优化后等价于 WHERE a='0' AND b='1' AND c='2',完全符合联合索引的最左前缀原则,且是精确匹配(=),因此能高效利用整个联合索引。

在第 X 层主迷宫的尽头,桐人和亚丝娜遇到了一扇名为「阶律之门」的机关门。门心的光幕会依次显现一串不下降的整数,形成一条非降序序列。 给定一个整数序列 [v1, v2, …, vd],其评分定义为: 其中 len! = 1 · 2 · … · len。特别地,空序列的评分为 1。 对任意序列 [v1, v2, …, vd],记 m 为其所有子序列评分的最大值,则该序列的配置长度定义为:在评分等于 m 的所有子序列中,长度的最大值。 现在,光幕显现了一组非降序整数序列 [a1, a2, …, an](即 a1 ≤ a2 ≤ … ≤ an)。对每个 k=1,2,…,n,请你计算前缀 [a1, a2, …, ak] 的配置长度。 子序列的定义:序列 x 是序列 y 的子序列,当且仅当 x 可由 y 删除若干(可能为零或全部)元素得到。子序列由下标集合唯一确定,因此即使元素值相同但位置不同,也视为不同的子序列。 Input 每个测试包含多个测试用例。第一行包含测试用例的数量 t(1 ≤ t ≤ 104)。测试用例说明如下。 每个测试用例的第一行都包含一个整数 n(1 ≤ n ≤ 105)—— 给定序列的长度。 每个测试用例的第二行包含 n 个整数 a1, a2, …, an(1 ≤ ai ≤ n)—— 给定序列。保证其元素不递减。 保证所有测试用例中 n 的总和不超过 5 × 105。 Output 对于每个测试用例,输出 n 个整数 —— 按 k 升序排列的序列 [a1, a2, …, ak] 的配置长度,每个整数后面紧接一个空格,每行最后紧接换行。 Sample Input 3 3 1 2 3 2 1 1 5 5 5 5 5 5 Sample Output 1 1 2 1 1 1 2 3 4 5 Hint 在第一个测试用例中: 对于前缀 [1]:所有子序列的最大评分为 1。评分等于 1 的子序列是 [1] 和空序列 []。其中长度最大的子序列是 [1],长度为 1。因此,[1] 的配置长度是 1。 对于前缀 [1, 2]:最大评分为 2。评分等于 2 的唯一子序列是 [2],长度为 1。因此,[1, 2] 的配置长度是 1。 对于前缀 [1, 2, 3]:最大评分为 3。评分等于 3 的子序列有 [3] 和 [2, 3]。其中长度最大的子序列是 [2, 3],长度为 2。因此,[1, 2, 3] 的配置长度是 2。 所以该测试用例的答案是:1 1 2。
最新发布
10-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值