【数据库】基于索引的扫描算法,不同类型索引下的选择与连接操作,不同的代价及优化

基于索引的算法

专栏内容

  • 手写数据库toadb
    本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。
    本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学习。

开源贡献

  • toadb开源库

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

  • 基于索引的算法
  • 前言
  • 概述
  • 索引类型
  • 使用索引的选择
    • 索引选择代价
    • 索引扫描对几种常见选择操作的优化
  • 使用索引的连接
  • 有序索引的连接
  • 总结
  • 结尾

在这里插入图片描述

前言

随着信息技术的飞速发展,数据已经渗透到各个领域,成为现代社会最重要的资产之一。在这个大数据时代,数据库理论在数据管理、存储和处理中发挥着至关重要的作用。然而,很多读者可能对数据库理论感到困惑,不知道如何选择合适的数据库,如何设计有效的数据库结构,以及如何处理和管理大量的数据。因此,本专栏旨在为读者提供一套全面、深入的数据库理论指南,帮助他们更好地理解和应用数据库技术。

数据库理论是研究如何有效地管理、存储和检索数据的学科。在现代信息化社会中,数据量呈指数级增长,如何高效地处理和管理这些数据成为一个重要的问题。同时,随着云计算、物联网、大数据等新兴技术的不断发展,数据库理论的重要性日益凸显。

概述

在一张表的一个或多个列属性上带有索引,使得一些没有索引时,不可行的算法,在使用索引后就可行了。

对基于索引的选择操作,尤其有作用,连接和其它二元操作也使用索引可以获得较好的效率。

本文将分享带有索引的表中进行索引扫描操作时的流程,代价的分析。

索引类型

我们先来看一下聚簇索引和非聚簇索引,因为它们两者在索引扫描下的代价差异是非常大的。

如果一个表的元组紧缩到能存储它们的尽可能少的数据块中,那么这个表是“聚簇”的,之前分享的几种算法的代价估计,都是基于这种假设的。
一个或多个属性上的聚簇索引,具有索引查询关键的所有元组都出现在能容纳它们的尽可能少的数据块中;

而一个非聚簇关系,是不能够有一个聚簇索引的,相反是可以的。

使用索引的选择

对于表扫描的最基本操作就是选择,我们通过读取表的所有元组,来执行一个选择,看那个元组能满足某一条件,并且返回结果元组。

如果表R上没有索引,那么我们只能遍历表的所有数据块,扫描每个数据块上的所有元组,代价就是数据块数据的IO次数,最差情况是数据块的数量同元组数量相等。

而当表上选择对应的列上建有索引时,我们可能通过索引找到元组所在的数据块,如果表对应的元组分类的数量为V,表的数据块总数为B,那么对应的磁盘IO计算方法为 B/V;

索引选择代价

假如每个查询关键字都是不一样的,那么V的数量可以认为是表的元组数量,它比表的数据块数量大的多,此时的代价磁盘IO数量近似为1,当然还会有一些额外的磁盘IO发生,原因如下:

  • 索引一般也要从磁盘上来读取,它也需要一些磁盘IO;
  • 当对应元组的块加载到内存中,符合条件的其它元组不在同一个块中,所以还会再额外读取块;
  • 尽管是聚簇的,但也不可能完全填满数据块,因为数据库在运行过程中要留有一定空间方便以后插入元组;所以数据块的数量比完全填满 要大一些;

索引扫描对几种常见选择操作的优化

  • 对于范围的选择,可以通过索引找到范围内的所有元组,一次取回所有元组,达到顺序读取的效果。

  • 对于多条件复杂选择,可以将多个逻辑查询是做串联,第一个通过索引查询,第二个在此基础上再选择,当然还有其它查询优化方法,将在后续文章中介绍。

使用索引的连接

当两个表R(X,Y)与表S(Y,Z)进行自然连接时,同时连接属性列上都建有索引。索引对于连接操作的变动如下:

  1. 读取表R对应的Y的索引块,并依次获取索引项RY;
  2. 从头开始读取表S对应的Y的索引块,查找RY是否存在;
  3. 如果不存在,继续重复步骤1;
  4. 如果存在,执行表R和表S对应元组的连接;
  5. 直到表S的索引块结束,继续重复步骤1;

最后表R的索引块处理完毕;整个过程类似与之前的介绍的连接步骤,区别是这里不再读取表的数据块,而索引往往相对数据来说,非常小。

假设表S中Y属性列的值分类数量为V(S),S表的元组数量为T(S),那么对于S表的IO次数为T(S)/V(S);而表R的元组数量为T®,那么对应的索引连接操作的代价为 T®T(S)/V(S),这时S表的代价占比较大。

如果外层R表较小时,整体代价下降较大。

有序索引的连接

对于连接属性上含有索引,而且它是一个有序的索引,如BTree索引,类似之前分享的基于排序的连接,而且使用一趟算法即可完成。

对于R上的索引,在S的索引中查找,如果不存在,此时不需要访问各自的表数据块;对于找到的索引项,取R的元组与S的相同元组进行连接;因为索引是有序的,按照S的索引顺次往下遍历,也可以一次性拿出S符合的索引项,再依次找到对应数据元组。

总结

当表上有索引时,可以利用索引减少加载大量表数据块的磁盘IO成本,但是当数据表比较小时,优化效果不明显,当数据表非常大时,索引的使用对于磁盘IO减少是非常大的。

解释器模式是一种行为型设计模式,用于构建解释器系统,如编译器或解释器等。在这种模式中,我们定义了一个抽象语法树(AST),并使用解释器来遍历AST并解释执行。

下面是一个简单的解释器模式实现,使用C语言编写,可以解释并输出"Hello World":

#include <stdio.h>
#include <stdlib.h>// 抽象语法树节点结构体定义
typedef struct Node {char *name; // 节点名称struct Node *children[10]; // 子节点数组int num_children; // 子节点数量
} Node;// 创建节点函数
Node *create_node(char *name) {Node *node = (Node *)malloc(sizeof(Node));node->name = name;node->num_children = 0;return node;
}// 添加子节点函数
void add_child(Node *parent, Node *child) {parent->num_children++;parent->children[parent->num_children - 1] = child;
}// 解释器函数,遍历AST并输出"Hello World"
void interpreter(Node *root) {if (root == NULL) {return;}if (strcmp(root->name, "print") == 0) {printf("Hello World\n");return;}for (int i = 0; i < root->num_children; i++) {interpreter(root->children[i]);}
}int main() {// 构建AST,根节点为"print",子节点为空Node *root = create_node("print");interpreter(root); // 遍历AST并输出"Hello World"return 0;
}

在上述代码中,我们定义了一个抽象语法树节点结构体Node,包含节点名称、子节点数组和子节点数量。然后,我们创建了create_nodeadd_child函数,用于构建AST。在interpreter函数中,我们遍历AST并判断根节点的名称是否为"print",如果是,则输出"Hello World"。如果是其他节点,则递归遍历其子节点。最后,在main函数中,我们构建了一个AST,根节点为"print",子节点为空,并调用interpreter函数来遍历AST并输出"Hello World"。

结尾

非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

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

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

相关文章

JDK8升级JDK11最全实践干货来了

1、前言 截至目前&#xff08;2023年&#xff09;&#xff0c;Java8发布至今已有9年&#xff0c;2018年9月25日&#xff0c;Oracle发布了Java11&#xff0c;这是Java8之后的首个LTS版本。那么从JDK8到JDK11&#xff0c;到底带来了哪些特性呢&#xff1f;值得我们升级吗&#x…

利用canal进行MySQL到ES的数据实时同步

1. 背景 项目中业务数据量比较大&#xff0c;每类业务表都达到千万级别&#xff0c;虽然做了分库分表&#xff0c;每张表数据控制在300W以下&#xff0c;但是效率还是达不到要求&#xff0c;为了提高查询效率&#xff0c;打算使用ES进行数据查询。 2. 同步原理 canal 模拟 My…

csapp-linklab之第二阶段“输出学号”实验报告

本阶段主题是链接中的“重定位”。两次重定位&#xff0c;一次是绝对地址重定位&#xff0c;一次是PC相对地址重定位。 本题目标依旧是输出学号&#xff0c;反汇编phase2.o&#xff0c;看到学号“0000000000”已经存放在只读数据区了。现在任务就是改do_pheas的指令和重定位表…

题目标题:乐乐摘苹果(杨鼎强)

一天乐乐去果园玩&#xff0c;发现一棵苹果树上结出10个苹果。乐乐跑去摘苹果。乐乐找到一个30厘米高的板凳&#xff0c;当她不能直接用手摘到苹果的时候&#xff0c;就会踩到板凳上再试试。 现在已知10个苹果到地面的高度&#xff0c;以及乐乐把手伸直的时候能够达到的最大高度…

Ubuntu系统Springboot项目Nginx安装(编译安装方式)

1.下载 nginx官网下载 Index of /download/ 2.解压 这里我下载的1.25.3版本&#xff0c;系统是ubuntu 解压 tar -zxvf nginx-1.25.3.tar.gz 3.编译安装 安装前需要执行安装一些系统依赖 3.1安装PCRE库 ubuntu&#xff1a;执行以下命令 sudo apt-get install libpcre…

uniapp2023年微信小程序头像+昵称分别获取

1、DOM <view class"m-user"><view class"user-info"><!--头像 GO--><button class"avatar avatar-wrapper" open-type"chooseAvatar" chooseavatar"onChooseAvatar"slot"right"><im…

c++实现程序单例运行的两种方式

第一种使用互斥体 // 使用互斥体保证单体运行 BOOL IsAlreadyRun() {HANDLE hMutex NULL;hMutex CreateMutex(NULL, FALSE, L"MYFLAG");if (hMutex ! NULL){if (ERROR_ALREADY_EXISTS GetLastError()){ReleaseMutex(hMutex);return TRUE;}}return FALSE; } int m…

国家高新技术企业认定,可以提前准备这些!

尽早获取核心自主知识产权 对于高新技术企业认定中有Ⅰ类和Ⅱ类知识产权之分。 其中&#xff0c;企业拥有的专利、植物新品种、国家新药、软件著作权等属于Ⅰ类核心知识产权&#xff0c;是高新技术企业认定的首要和必须条件&#xff0c;在高企认定中也会给申请人带来相应较高…

获取国内城市编码API

获取国内城市编码API接口 一、获取国内城市编码接口二、使用步骤1、接口2、请求参数 三、 案例和demo 一、获取国内城市编码接口 一款免费的帮助你获取取国内城市编码的接口 二、使用步骤 1、接口 重要提示:建议使用https协议,当https协议无法使用时再尝试使用http协议 请求…

【Lidar】基于Python的Open3D库可视化点云数据

1 Open3D库介绍 1.1 介绍 Open3D是一个开源的3D数据处理库&#xff0c;发布于2015年&#xff0c;目前已经更新到0.17.0版本。它基于MIT协议开源许可&#xff0c;使用C11实现&#xff0c;并经过高度优化&#xff0c;还通过Python Pybinding提供了前端Python API。 Open3D为开发…

C语言之atoi函数的使用和模拟实现

C语言之atoi函数的使用和模拟实现 1. atoi函数介绍 函数声明如下&#xff1a; int atoi (const char * str);atoi是用来将字符串中第一次出现的数字字符&#xff0c;转为一个整数 跳过空白字符&#xff0c;&#xff08;空白字符包括&#xff1a;空格 ’ ’ &#xff0c;换页…

我叫:基数排序【JAVA】

1.自我介绍 基数排序(radix sort)属于“分配式排序” (distribution sort)&#xff0c;又称“桶子法” (bucket sort)或bin sort,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,是‘桶排序’的扩展 2.基本思想 将所有待比较数值统一为同样的数位长度,数位较短的数…

docker start一个容器之后,怎么进入这个容器界面

要进入已经启动的 docker 容器的交互式终端&#xff0c;可以使用 docker exec 命令。这个命令可用于在运行中的容器内部执行命令或脚本&#xff0c;并以交互模式与容器进行交互&#xff0c;具体格式如下&#xff1a; # docker exec -it [container_id or container_name] /bin/…

专业的调查问卷平台推荐:提升数据收集与分析效率

无论是学生还是职场人士&#xff0c;想做好一份调查问卷&#xff0c;关键先要确定调查的主题&#xff0c;然后确定调查人群&#xff0c;编辑问题&#xff0c;最后能够尽可能的美化问卷调查的主题。 想要做到这几点&#xff0c;就要要求问卷调查平台: 1、能够帮助你快速制作出一…

【开题报告】基于模糊控制的花卉光照时间控制系统

题 目 基于模糊控制的花卉光照时间控制系统 一、研究目的和意义 用光电传感器检测自然光&#xff0c;根据花卉开花时长&#xff0c;用MATLAB软件&#xff0c;使用模糊控制算法&#xff0c;对测得数据进行分析&#xff0c;得出结论&#xff0c;并传回下位机控制电机运动…

软件测试测试文档的编写和阅读

在软件测试中的流程中&#xff0c;测试文档也是一个重要的流程&#xff0c;所以测试人员也需要学习测试文档的编写和阅读。 一、定义&#xff1a; 测试文档&#xff08;Testing Documentation&#xff09;记录和描述了整个测试流程&#xff0c;它是整个测试活动中非常重要的文…

QT应用示例

一个简单的QT应用示例&#xff1a;创建一个窗口程序。 首先&#xff0c;确保已经安装了Qt开发环境。接下来&#xff0c;按照以下步骤创建一个简单的窗口程序&#xff1a; 1. 打开Qt Creator&#xff0c;点击“新建文件或项目”。 2. 选择“应用程序”&#xff0c;然后点击“下…

年终好价节有什么必买的数码好物?值得入手的数码好物推荐

大家是不是都没听说过好价节&#xff1f;直白点说就是原来的双十二购物狂欢节&#xff0c;只不过换一个说法&#xff0c;不过今年毕竟是第一年换个说法&#xff0c;所以淘宝年终好价节优惠还是值得我们期待的&#xff01;作为年前的最后一波大促&#xff0c;一起来看看有哪些好…

QML通用属性 pyside6

在 QML 中&#xff0c;几乎所有组件都继承自 Item 类型&#xff0c;因此它们共享一些通用的属性。 QML 组件通用属性 位置和尺寸 x 和 y: 组件在其父元素中的位置坐标 Item {x: 100y: 100 }width 和 height: 组件的宽度和高度 Item {width: 200height: 100 }z: 组件在 Z 轴…

SQL server界面操作链接服务器

1.打开链接服务器&#xff0c;右击连接服务器“新建链接服务器” 2.输入链接服务器名称和数据源 3.安全性中输入密码建立远程连接&#xff0c;点击确定&#xff1a; 4.打开新建的连接服务器&#xff0c;测试连接&#xff1a; 注意:链接服务器必须在局域网执行&#xff0c;不是同…