[数据库之十一] 数据库索引之联合索引

  执行数据库查询时,通常查询条件是多对个属性进行判断和约束,对于这种类型的查询,如果存在多个索引则使用多个索引,或者使用建立在多属性搜索码上的索引,这样能提高查询效率。

一、使用多个单码索引

  假设数据表 instructor 有两个单码索引,分别建立在 dept_namesalary 上。为了找到金融系中工资为 80000 的所有老师,使用以下 SQL:

select ID
from   instructor
where  dept_name = "Finance" and salary = 80000;



  可以使用以下几种查询策略:

1、使用 dept_name 上的索引,找出属于金融系的所有记录,再检查每条记录是否满足 salary = 80000。
2、使用 salary 上的索引,找出所有工资为 80000 的记录,再检查每条记录是否满足 dept_name = "Finance"。
3、利用 dept_name 上的索引找出指向属于金融系的记录的所有指针。同样利用 salary 上的索引找出指向工资等于 80000 的记录的所有指针。两个指针集合的交集,即为所有满足查询条件的记录的所有指针。


  三种策略只有第三种利用了存在的多种索引的优势,但是在以下条件下也可能是糟糕的选择:

  • 属于金融系的记录太多

  • 工资为 80000 的记录太多

  • 属于金融系且工资为 80000 的记录只有几个



    因为为了得到一个很小的结果集,必须扫描大量指针,策略的执行效果取决于索引属性值的分布。


二、多码索引(联合索引)

1、最左前缀匹配规则

  为了解决上面的问题,一个可行的方案是在复合的搜索码(dept_name, salary)上建立和使用索引,这就是联合索引

  联合索引有个规则,叫最左前缀匹配规则,即 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配,值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。



  比如对于SQL:

select ID
from   instructor
where  dept_name = "Finance" and salary = 80000;select ID
from   instructor
where  dept_name = "Finance";

  都是可以匹配索引的,查询条件一个是(dept_name, salary),一个是(dept_name),复合最左前缀匹配规则。


  但是对下面的查询是不匹配的:

where  salary = 80000;

  因为前面的查询条件没有 dept_name,联合索引最左边的属性 dept_name 没有匹配到,就不会对后面的属性 salary 使用索引。


  对下面的查询也是可以匹配到索引的

where salary = 80000 and dept_name = "Finance";

  因为数据库有优化器会自动调整 salary、dept_name 的顺序与索引顺序一致。


  遇到范围查询,会停止对后面属性的索引匹配,比如建立索引(a, b, c, d),where 后条件为

a = 1 and b = 2 and c > 3 and d = 4

  那么,a,b,c三个字段能用到索引,而d就匹配不到。因为遇到了范围查询,但是如果把索引改成(a, b, d, c)则又可以匹配了,因为数据库优化器会自动把查询条件的属性顺序调整为

a = 1 and b = 2 and d = 4 and c > 3



2、数据结构

假设,我们对(a,b)字段建立索引,那么入下图所示

对于联合索引(a, b),先按 a 进行排序,相同的 a 内部才按 b 进行排序,对于整个 B+ 树来说,a 在其中是有序的,按照前序遍历的顺序,上图中各个树节点 a 的值分别为 1, 1, 2, 2, 2, 3, 3。

而 b 是一种全局无需,局部有序的状态,即相同的 a 内部的有序。同样按照前序遍历的顺序,各个结点 b 的值分别为 1, 2, 1, 4, 4, 1, 2。因此对于 b = 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 字段用不上索引。

所以,根据最左前缀匹配原则,在遇到范围查询时,就会停止匹配。



3、实战
题型一

如果sql为

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

如何建立索引?

如果此题回答为对(a,b,c)建立索引,那都可以回去等通知了。 此题正确答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以,重点要的是将区分度高的字段放在前面,区分度低的字段放后面。像性别、状态这种字段区分度就很低,我们一般放后面。

例如假设区分度由大到小为b,a,c。那么我们就对(b,a,c)建立索引。在执行sql的时候,优化器会 帮我们调整where后a,b,c的顺序,让我们用上索引。


题型二

如果sql为

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

如何建立索引?

如果此题回答为对(a,b)建立索引,那都可以回去等通知了。 此题正确答法是,对(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,毕竟最左匹配原则遇到范围查询就停止匹配。 如果对(b,a)建立索引那么两个字段都能用上,优化器会帮我们调整where后a,b的顺序,让我们用上索引。


题型三

如果sql为

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

如何建立索引? 此题回答也是不一定,(b,a)或者(b,c)都可以,要结合具体情况具体分析。

拓展一下

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

怎么建索引?嗯,大家一定都懂了!

(a, b, c) 或 (b, a, c) 根据区分度决定 a 前还是 b 前。


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

如何建立索引? 这还需要想?一看就是对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序! 那么

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

如何建立索引? 对(a)建立索引,因为a的值是一个范围,这个范围内b值是无序的,没有必要对(a,b)建立索引。

拓展一下

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

怎么建索引?

(a, b, c) 或 (b, a, c) 根据区分度决定 a 前还是 b 前。


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

如何建立索引?

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



喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/79201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

增强学习(Reinforcement Learning)简介

增强学习&#xff08;Reinforcement Learning&#xff09;简介 增强学习是机器学习的一种范式&#xff0c;其核心目标是让智能体&#xff08;Agent&#xff09;通过与环境的交互&#xff0c;基于试错机制和延迟奖励反馈&#xff0c;学习如何选择最优动作以最大化长期累积回报。…

PaddlePaddle 和PyTorch选择与对比互斥

你遇到的错误信息如下&#xff1a; RuntimeError: (PreconditionNotMet) Tensors dimension is out of bound.Tensors dimension must be equal or less than the size of its memory.But received Tensors dimension is 8, memorys size is 0.[Hint: Expected numel() * Size…

vison transformer vit 论文阅读

An Image is Worth 16x16 Words 20年的论文看成10年的哈斯我了 [2010.11929] 一张图像胜过 16x16 个单词&#xff1a;用于大规模图像识别的转换器 --- [2010.11929] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 为什么transformer好训练&am…

依赖关系-根据依赖关系求候选码

关系模式R&#xff08;U, F&#xff09;, U{}&#xff0c;F是R的函数依赖集&#xff0c;可以将属性分为4类&#xff1a; L: 仅出现在依赖集F左侧的属性 R: 仅出现在依赖集F右侧的属性 LR: 在依赖集F左右侧都出现的属性 NLR: 在依赖集F左右侧都未出现的属性 结论1: 若X是L类…

SAP note 3565626 : Baltimore CyberTrust 根证书即将过期

SAP note 3565626 &#xff1a; Baltimore CyberTrust 根证书即将过期 20250512 2025年5月9日 症状 您已收到来⾃ SAP Integration Suite/Cloud Integration 服务的通知邮件&#xff0c; 建议 Baltimore CyberTrust 根证书将于 2025 年 5 ⽉ 12 ⽇ 过期&#xff0c;其中 Balt…

算法精讲:字母异位词分组问题剖析

算法精讲:字母异位词分组问题剖析 一、引言 在算法的学习与实践中,字符串相关的问题一直是重点和难点。今天我们要深入探讨的“字母异位词分组”问题,不仅考验对字符串操作的理解,还涉及到数据结构的巧妙运用。通过解决这个问题,我们能进一步提升算法思维和代码实现能力。…

【每日八股】复习 Redis Day7:应知应会的 33 条 Redis 基础八股文

应知应会的 33 条 Redis 基础八股文 今天对 Redis 八股文进行收官总结&#xff0c;共收录了 33 条基础八股文。 文章目录 应知应会的 33 条 Redis 基础八股文Redis 持久化简述 Redis 持久化的两种策略&#xff1f;AOF 的三种持久化策略&#xff1f;AOF 磁盘重写机制&#xf…

k8s之探针

探针介绍&#xff1a; 编排工具运行时&#xff0c;虽说pod挂掉会在控制器的调度下会重启&#xff0c;出现pod重启的时候&#xff0c;但是pod状态是running,无法真实的反应当时pod健康状态&#xff0c;我们可以通过Kubernetes的探针监控到pod的实时状态。 Kubernetes三种探针类…

记9(Torch

目录 1、Troch 1、Troch 函数说明举例torch.tensor()torch.arange()创建张量创建一个标量&#xff1a;torch.tensor(42)创建一个一维张量&#xff1a;torch.tensor([1, 2, 3])创建一个二维张量&#xff1a;torch.tensor([[1, 2], [3, 4]])生成一维等差张量&#xff1a;语法&am…

flask开启https服务支持

目录 一、背景 二、开启https支持 三、自签名 1、安装openssl 2、验证安装 3、自签名 四、编写代码 五、访问https接口 一、背景 最近在做自动化业务&#xff0c;需要兼容现在主流的框架开发的前端页面&#xff0c;于是到github找到了几个项目&#xff0c;clone下来项目并…

路由交换实验

案例一&#xff1a;实施和配置RIPV2 1.给AR1配置接口 查看R1接口配置情况 2.配置三台路由的RIP协议&#xff0c;版本为version2 &#xff0c;关闭自动汇总&#xff0c;通告所有的直连接口 案例二&#xff1a;配置多区域的OSPF协议 1.配置R1的接口IP地址参数 2.配置r2,r3的接口参…

北斗导航 | RTKLib中重难点技术,公式,代码

Rtklib 一、抗差自适应卡尔曼滤波1. **核心难点**2. **公式与代码实现**二、模糊度固定与LAMBDA算法1. **核心难点**2. **LAMBDA算法实现**3. **部分模糊度固定技术**三、伪距单点定位与误差修正1. **多系统多频点修正**2. **接收机钟差与系统间偏差**四、动态模型与周跳处理1.…

RT-Thread 深入系列 Part 2:RT-Thread 内核核心机制深度剖析

摘要: 本文从线程管理、调度器原理、中断处理与上下文切换、IPC 同步机制、内存管理五大核心模块出发,深入剖析 RT-Thread 内核实现细节,并辅以源码解读、流程图、时序图与性能数据。 目录 线程管理与调度器原理 1.1 线程控制块(TCB)结构 1.2 就绪队列与优先级调度 1.3 时…

STM32部分:3、STM32CubeMX 工程创建

飞书文档https://x509p6c8to.feishu.cn/wiki/LfMpwjktZiMAuMkayt6c0LGZnpx 1、打开STM32CUBEMX&#xff0c;选择File->New Project 如果首次使用&#xff0c;可能会自动下载一些依赖包&#xff0c;可以等待下载完成。 2、选择对应芯片 MCU/MPU Selector->输入“STM32F1…

第十五章,SSL VPN

前言 IPSec 和 SSL 对比 IPSec远程接入场景---client提前安装软件&#xff0c;存在一定的兼容性问题 IPSec协议只能够对感兴趣的流量进行加密保护&#xff0c;意味着接入用户需要不停的调整策略&#xff0c;来适应IPSec隧道 IPSec协议对用户访问权限颗粒度划分的不够详细&…

深度学习系统学习系列【4】之反向传播(BP)四个基本公式推导

文章目录 补充知识&#xff1a;∇ 和 ⊙ 运算符详解∇ (nabla) 运算符⊙ (圆圈点) 运算符 反向传播基本公式计算图和基本定义BP1&#xff1a;输出层误差推导BP1公式的重要性实际例子BP2第 l l l层误差推导BP3 &#xff1a;损失函数关于偏置(b)偏导的推导BP4&#xff1a; 损失函…

极狐Gitlab 如何创建并使用子群组?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 子群组 (BASIC ALL) 您可以将极狐GitLab 群组组织成子群组。您可以使用子群组&#xff1a; 内部和外部组织分开。因为每个子…

HarmonyOS基本的应用的配置

鸿蒙HarmonyOS组建页面 1、创建ets文件并配置2、修改main_pages.json文件3、修改EntryAbility.ets文件&#xff08;启动时加载的页面&#xff09; 1、创建ets文件并配置 Index.ets是创建项目自动构建生成的&#xff0c;我们可以将其删除掉&#xff0c;并重新在page文件夹下创建…

强化学习三大基本方法-DP、MC、TD

强化学习进阶 本文主要讲解 动态规划法&#xff08;Dynamic Programming DP&#xff09;蒙特卡洛法&#xff08;Monte Carlo MC&#xff09;时序差分法&#xff08;Temporal Difference TD&#xff09; 1. 动态规划法 1.1 动态规划概念 动态规划核心思想&#xff1a; 其核心…

《Spring Boot 3.0全新特性详解与实战案例》

大家好呀&#xff01;今天让我们轻松掌握Spring Boot 3.0的所有新特性&#xff01;&#x1f680; &#x1f4cc; 第一章&#xff1a;Spring Boot 3.0简介 1.1 什么是Spring Boot 3.0&#xff1f; Spring Boot 3.0就像是Java开发者的"超级工具箱"&#x1f9f0;&…