当前位置: 首页 > news >正文

《MySQL系列-InnoDB引擎35》索引与算法-B+树索引的使用

B+树索引的使用

1 不同应用中B+树索引的使用

在OLTP中,B+树索引建立后,对该索引的使用应该只是通过该索引取得表中少部分的数据。这时建立B+树索引才是有意义的,否则即使建立了,优化器也可能不选择使用索引。

在OLAP中,如果是复杂的查询,要涉及多张表之间的连接操作,因此添加索引是有意义的。但是如果连接使用的hash join,那么索引可能又变的不那么重要了。不过在OLAP中,通常会需要对时间字段进行索引,这是因为大多数统计需要根据时间维度来进行数据的筛选。

2 联合索引

联合索引是指对表上的多个列进行索引。联合索引的创建方法和单个索引的创建方法一样,不同之处仅在于有多个索引列。

比如:对创建索引index_a_b (a,b),那么在查询的时候select * from table where a=xx and b=xx是可以使用(a,b)这个索引的。对于单列的查询select * from table where a=xxx也可以使用这个(a,b)索引。但是select * from table where b=xxx是用不到联合索引的。

联合索引的另一个好处就是已经对第二个键值进行了排序处理。例如:使用(userid,sys_date)联合索引,在查询userid并且要求有序的时候,就会默认使用(userid,sys_date)索引。

1)创建索引

mysql> create table index_test(-> userid int unsigned not null,-> sys_date date,-> key key_u (userid),-> key key_u_s (userid,sys_date)-> )engine=innodb;
Query OK, 0 rows affected (0.03 sec)

2)插入数据

mysql> insert into index_test values(1,'2020-01-01');
mysql> insert into index_test values(2,'2022-01-01');
mysql> insert into index_test values(3,'2022-05-01');
mysql> insert into index_test values(4,'2021-05-01');

3)查询userid,不要求排序

只查询userid的时候,可以看到在possible_keys中可以有两个索引提供使用,分别是单个userid索引的ley_u和(user_id,sys_date)的联合索引key_u_s。但是最终优化器选择是userid,因为该索引的叶子节点包含单个键值,所以理论上一个页能存放的记录应该更多。

mysql> explain select * from index_test where userid = 2\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: index_testpartitions: NULLtype: ref
possible_keys: key_u,key_u_skey: key_ukey_len: 4ref: constrows: 1filtered: 100.00Extra: NULL
1 row in set, 1 warning (0.00 sec)

4)查询userid,要求排序

当查询userid,并要求排序的时候,possible_keys既可以使用key_u索引,也可以使用key_u_s索引。但是优化器选择了ley_u_s索引,因为这个联合索引中sys_date字段已经排序好了。只需要根据联合索引取出数据,无须再对sys_date做一次额外的排序操作。

mysql> explain select * from index_test where userid = 2 order by sys_date desc limit 3\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: index_testpartitions: NULLtype: ref
possible_keys: key_u,key_u_skey: key_u_skey_len: 4ref: constrows: 1filtered: 100.00Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)

5)查询userid,要求排序,并强制使用key_u索引

如果是强制使用key_u索引,可以在Extra中看到有using filesort,即需要额外一次排序才能完成查询,而这次显然需要对列sys_date排序。

mysql> explain select * from index_test force index(key_u) where userid = 2 order by sys_date desc limit 3\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: index_testpartitions: NULLtype: ref
possible_keys: key_ukey: key_ukey_len: 4ref: constrows: 1filtered: 100.00Extra: Using index condition; Using filesort
1 row in set, 1 warning (0.00 sec)

3 覆盖索引

InnoDB存储引擎支持覆盖索引,即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。使用覆盖索引的一个好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。

例如:当一个表里有聚集索引和辅助索引时,在count数据的时候,innodb会自动优化使用辅助索引,而不是使用聚集索引。

4 优化器选择不适应索引的情况

在某些情况下,当执行explain命令进行SQL语句分析时,会发现优化器并没有选择索引去查找数据,而是通过扫描聚集索引,也就是直接进行全表扫描来得到数据。这种情况多发生于范围查找、join连接等情况下。

5 索引提示

MySQL数据库支持索引提示(index hint),显式的告诉优化器使用哪个索引。大概两种情况下需要用到索引提示:

  • MySQL数据库的优化器错误的选择了某个索引,导致SQL语句运行很慢。对于目前的SQL版本,可能很少会遇见这种问题。如果存在的话,可以强制优化器使用某个索引,以此来提高运行的速度。
  • 某SQL语句可以选择的索引非常多,这时优化器选择执行时间的开销可能会大于SQL语句本身。例如,优化器分析range查询本身就是比较耗时的操作。这时可以通过Index Hint来强制优化器不进行各个执行路径的成本分析,直接指定索引完成查询。

使用force index来指定索引是可行的。

6 Multi-Range Read优化

MySQL5.6开始支持Multi-Range Read(MRR)优化。其目的就是减少磁盘的随机访问,并且随机访问转化为较为顺序的数据访问,这时对于IO-bound类型的SQL查询可以带来性能极大的提示。Multi-Range Read优化可适用于range,ref,eq_ref类型的查询。

MRR优化的好处:

  • MRR使数据访问变得较为顺序。在查询辅助索引时,首先恩据得到得查询结果,按照主键进行排序,并按照主键顺序进行书签查找。
  • 减少缓冲池中页被替换的次数
  • 批量处理对键值的查询操作

对于InnoDB和MyISAM存储引擎的范围查询和JOIN查询操作,MRR的工作方式如下:

  • 将查询得到的辅助索引键值存放于一个缓存中,这时缓存中的数据是根据辅助索引键值排序的。
  • 将缓存中的键值根据RowID进行排序
  • 根据RowID的排序顺序来访问实际的数据文件。

此外,若InooDB存储引擎或者MyISAM存储引擎的缓冲池不是足够大,即不能存放下一张表中所有的数据,此时频繁的离散读操作还会导致缓存中的页被替换出缓冲池,然后又不断的被读入缓冲池。若是按照主键顺序进行访问,则可以将此重复行为降为最低。

是否启用Multi-Range Read优化可以通过参数optimizer_switch中的标记来控制。当mrr=on时,表示启用multi-range read优化。mrr_cost_based标记表示是否通过cost based的方式来选择是否启用mrr。

若mrr设为on,mrr_cost_based设为off,则总是启用multi-range read优化。例如可通过如下指令设置multi-range read优化总是处于开启状态:

mysql> set @@optimizer_switch='mrr=on,mrr_cost_based=off';

参数read_rnd_buffer_size用来控制键值的缓冲区大小,当大于该值时,则执行器对已经缓冲的数据根据RowID进行排序,并通过RowID来取得行数据。该值默认为256K。

mysql> select @@read_rnd_buffer_size\G;
*************************** 1. row ***************************
@@read_rnd_buffer_size: 262144
1 row in set (0.00 sec)

7 Index Condition Pushdown (ICP)优化

和Multi-Range Read一样,Index COndition Pushdown也是MySQL5.6开始支持的查询优化的方式。之前在进行索引查询的时候,首先根据索引来查找记录,然后根据where条件来过滤记录。在支持Index Condition Pushdown后,MySQL数据库会在去除索引的同时,判断是否可以进行where条件的过滤,也就是将where的部分过滤操作放在存储引擎层。在某些查询下,可以大大减少上层SQL对记录的索取(fetch),从而提高数据库的整体性能。

Index Condition Pushdown优化支持range、ref、eq_ref、ref_or_null类型的查询,当前支持MyISAM和InnoDB存储引擎。当优化器选择Index Condition Pushdow优化时,可在执行记录的列Extra看到Using index condition的提示。

相关文章:

《MySQL系列-InnoDB引擎35》索引与算法-B+树索引的使用

B树索引的使用 1 不同应用中B树索引的使用 在OLTP中,B树索引建立后,对该索引的使用应该只是通过该索引取得表中少部分的数据。这时建立B树索引才是有意义的,否则即使建立了,优化器也可能不选择使用索引。 在OLAP中,…...

【EHub_tx1_tx2_E100】不止科技NVISTAR ROC 300激光雷达Ubuntu18.04+ROS1ROS2 评测

介绍NVISTAR 的二维DTOF激光雷达 ROC 300在EHub_tx1_tx2_E100载板,TX1核心模块环境(Ubuntu18.04)下测试ROS1驱动和ROS2的驱动,打开使用RVIZ 查看点云数据,本文的前提条件是你的TX1里已经安装了ROS1版本:Mel…...

C语言函数大全--d开头的函数

C语言函数大全 本篇介绍C语言函数大全–d开头的函数 1. detectgraph 1.1 函数说明 函数声明函数功能void detectgraph(int *graphdriver, int *graphmode);通过检测硬件确定图形驱动程序和模式 1.2 演示示例 #include <graphics.h> #include <stdlib.h> #incl…...

基于springboot实现福聚苑社区团购演示【项目源码】

基于springboot实现福聚苑社区团购演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#…...

动静态库的制作

文章目录&#xff1a;什么是程序库&#xff1f;动态链接和静态链接动静态库的认识静态库的创建与使用创建使用动态库的创建与使用创建使用什么是程序库&#xff1f; 程序库&#xff1a;一般是软件作者为了发布方便、替换方便或二次开发目的&#xff0c;而发布的一组可以单独与应…...

QMS-云质-质量软件-客诉,为什么应该用两段式来处理

-云质QMS原创文章&#xff0c;转载请注明来源- 客户满意度是决定企业是否能够基业长青的关键因素之一。 如果客诉处理的不好&#xff0c;会极大影响客户的满意程度。 通常处理客诉分为两个阶段。 第一个阶段是快反遏制&#xff0c;想方设法快速答复和解决客户提出的问题&…...

JS:关于邮箱的正则表达式及规则

常用正则表达式—邮箱&#xff08;Email&#xff09; 要验证一个字符串是否为邮箱的话&#xff0c;首先要了解邮箱账号的格式。我尝试过在网上找出一个标准的格式&#xff0c;但是很遗憾我没有找到。我也尝试使用RFC标准来判断邮箱的格式&#xff0c;但是也没有结果。网上些博…...

两句话,ChatGPT帮我写一个打飞机的游戏

大家好&#xff0c;我是全村的希望今天的主题是让 chatGPT 来帮我们写一个打飞机的游戏记得我刚学 Python 的时候&#xff0c;看的那本很经典的入门书《Python 编程&#xff1a;从入门到实践》&#xff0c;里面就有小项目就是教你编写一个打飞机的游戏我那时候是对着书一个一个…...

计算机图形学14:三维图形的投影变换

作者&#xff1a;非妃是公主 专栏&#xff1a;《计算机图形学》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录专栏推荐专栏系列文章序一、三维图形的投…...

【ChatGPT4】王老师零基础《NLP》(自然语言处理)第二课

我的已经在起、点开了书《王老师带我成为救世主》&#xff0c;那个更新及时 &#xff08;1&#xff09;---------------------------------------------------------------------------------------- 我&#xff1a; 1我/喜欢/吃/苹果&#xff0c;因为/它/们/很/好吃。 2 Th…...

设计模式之中介者模式在前端的应用

文章目录中介者模式在前端的应用场景1.实现组件之间的松耦合2. 实现异步请求的协同3. 实现事件驱动的编程模型4. 实现复杂交互的协调总结中介者模式在前端的应用场景 中介者模式是一种常见的设计模式&#xff0c;它可以将对象之间的通信集中处理&#xff0c;从而提高系统的可维…...

2023年还能入行程序员吗?工作3年以上的黑马老学员怎么说?

很多人觉得&#xff0c;毕业3年&#xff0c;不过是毕业第1年的重复&#xff0c;键盘Ctrl、C和V键磨损更严重了。妥妥属于光涨年龄&#xff0c;不涨经验&#xff1b;只涨体重&#xff0c;不涨工资…… 他们不理解&#xff0c;为什么同样的起跑线&#xff0c;有人发展神速&#…...

接收机的噪声来源与噪声分析

噪声分类 射频接收机中的噪声主要可以分为两类&#xff1a;内部噪声和外部噪声。 内部噪声 内部噪声主要来自于接收机内部的放大器、混频器、本振等元件所产生的噪声。根据不同的产生机制&#xff0c;内部噪声可以分为以下几类&#xff1a; a. 电感噪声&#xff1a;由于电感…...

Android FrameWork——SystemServer

Android系统在启动的时候有两个非常重要的进程&#xff0c;一个是Zygote&#xff0c;另一个就是system_server。SystemServer是系统用来启动service的入口&#xff0c;比如我们常用的AMS&#xff0c;WMS&#xff0c;PMS等等都是由它创建的。 system_server进程的启动 system_…...

婴儿推车ASTMF883测试

1.cpc认证是总称&#xff0c;cpc认证下边有很多的标准&#xff0c;常见的有ASTM F963&#xff08;铅含量&#xff09;、CPSIA&#xff08;邻苯8P&#xff09;、ASTM F833&#xff08;婴儿车&#xff09;等&#xff1b; 2.婴儿车ASTM认证是什么 2019年8月2日&#xff0c;美国消…...

射频接收机概述

接收机架构 射频接收机架构是指电子设备中用于接收无线电信号的部分。它通常由前置放大器、中频放大器、混频器、局部振荡器和带通滤波器等组成。以下是一个基本的射频接收机架构&#xff1a; 前置放大器&#xff1a;前置放大器的作用是放大接收天线接收到的微弱无线电信号&am…...

实验三Numpy知识点总结

熟悉和使用NumPy模块 import numpy as np一、完成下列数组操作与运算。 &#xff08;1&#xff09;创建2行4列的数组arr_a&#xff0c;数组中的元素为0至7&#xff0c;要求用arange()函数创建。 arr_anp.arange(8) arr_a.resize(2,4) print(arr_a)[[0 1 2 3][4 5 6 7]]&…...

Code Review时学到的技巧之isAssignableFrom

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年4月1日 &#x1…...

IP协议以及相关技术

这里写目录标题前言正文IP基本认识IP的作用IP和MAC的关系IP地址的基础知识IP地址定义IP地址分类(IPv4)无分类IP地址CIDR子网掩码IPv6基础知识相关技术DNS域名解析ARPDHCPNATICMPIGMP总结参考连接前言 大家好&#xff0c;我是练习两年半的Java练习生&#xff0c;今天我们来讲一…...

SpringBoot 项目使用 Sa-Token 完成登录认证

一、设计思路 对于一些登录之后才能访问的接口&#xff08;例如&#xff1a;查询我的账号资料&#xff09;&#xff0c;我们通常的做法是增加一层接口校验&#xff1a; 如果校验通过&#xff0c;则&#xff1a;正常返回数据。如果校验未通过&#xff0c;则&#xff1a;抛出异…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...