三星索引概念

三星索引概念 对于一个查询而言,一个三星索引,可能是其最好的索引。如果查询使用三星索引,一次查询通常只需要进行一次磁盘随机读以及一次窄索引片的 扫描,因此其相应时间通常比使用一个普通索引的响应时间少几个数量级。 三星索引概念是在《Rrelational Database Index Design and the optimizers》 一书 (这本书也是《高性能MySQL》作者强烈推荐的一本书)中提出来的。原文如下: The index earns one star if it places relevant rows adjacent to each other, a second star if its rows are sorted in the order the query needs, and a final star if it contains all the columns needed for the query. 索引将相关的记录放到一起则获得一星; 如果索引中的数据顺序和查找中的排列顺序一致则获得二星; 如果索引中的列包含了查询中需要的全部列则获得三星。 二星(排序星): 在满足一星的情况下,当查询需要排序,group by、 order by,如果查询所需的顺序与 索引是一致的(索引本身是有序的),是不是就可以不用再另外排序了,一般来说排序 可是影响性能的关键因素。 三星(宽索引星): 在满足了二星的情况下,如果索引中所包含了这个查询所需的所有列(包括 where 子句 和 select 子句中所需的列,也就是覆盖索引),这样一来,查询就不再需要回表了, 减少了查询的步骤和IO请求次数,性能几乎可以提升一倍。 一星按照原文稍微有点难以理解,其实它的意思就是:如果一个查询相关的索引行是相 邻的或者至少相距足够靠近的话,必须扫描的索引片宽度就会缩至最短,也就是说,让 索引片尽量变窄,也就是我们所说的索引的扫描范围越小越好。 这三颗星,哪颗最重要?第三颗星。因为将一个列排除在索引之外可能会导致很多磁盘 随机读(回表操作)。第一和第二颗星重要性差不多,可以理解为第三颗星比重是50%, 第一颗星为27%,第二颗星为23%,所以在大部分的情况下,会先考虑第一颗星,但会根 据业务情况调整这两颗星的优先度。 达成三星索引 现在有表 create table customer( cno int, lname varchar(10), fname varchar(10), sex int, weight int, city varchar(10));建立索引 create index idx_cust on customer(city,lname,fname,cno); 对于下面的SQL而言,这是个三星索引 select cno,fname from customer where lname =’xx’ and city =’yy’ order by fname; 来评估下: 第一颗星:所有等值谓词的列,是组合索引的开头的列,可以把索引片缩得很窄,符 合。 第二颗星:order by的fname字段在组合索引中且是索引自动排序好的,符合。 第三颗星:select中的cno字段、fname字段在组合索引中存在,符合。 达不成三星索引 现在有表 CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_name` varchar(100) DEFAULT NULL, `sex` int(11) DEFAULT NULL, `age` int(11) DEFAULT NULL, `c_date` datetime DEFAULT NULL, PRIMARY KEY (`id`), ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; SQL语句如下: select user_name,sex,age from test where user_name like 'test%' and sex =1 ORDER BY age 如果我们建立索引(user_name,sex,age): 第三颗星,满足 第一颗星,满足 第二颗星,不满足,user_name 采用了范围匹配,sex 是过滤列,此时age 列无法保证 有序的。 上述我们看到,此时索引(user_name,sex,age)并不能满足三星索引中的第二颗星(排 序)。 于是我们改改,建立索引(sex, age,user_name): 第一颗星,不满足,只可以匹配到sex,sex选择性很差,意味着是一个宽索引片, 第二颗星,满足,等值sex 的情况下,age是有序的, 第三颗星,满足,select查询的列都在索引列中,对于索引(sex,age,user_name)我们可以看到,此时无法满足第一颗星,窄索引片的需 求。 以上2个索引,都是无法同时满足三星索引设计中的三个需求的,我们只能尽力满足2 个。而在多数情况下,能够满足2颗星,已经能缩小很大的查询范围了,具体最终要保留 那一颗星(排序星 or 窄索引片星),这个就需要看查询者自己的着重点了,无法给出 标准答案。 主键尽量是很少改变的列 我们知道,行是按照聚集索引物理排序的,如果主键频繁改变(update),物理顺序会改 变,MySQL要不断调整B+树,并且中间可能会产生页面的分裂和合并等等,会导致性能会 急剧降低。 处理冗余和重复索引 MySQL允许在相同列上创建多个索引,无论是有意的还是无意的。MySQL需要单独维护重 复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能。重复 索引是指在相同的列上按照相同的顺序创建的相同类型的索引。应该避免这样创建重复 索引,发现以后也应该立即移除。 有时会在不经意间创建了重复索引,例如下面的代码: CREATE TABLE test ( ID INT NOT NULL PRIMARY KEY, A INT NOT NULL, B INT NOT NULL, UNIQUE(ID), INDEX(ID) ) ENGINE=InnoDB; 这里创建了一个主键,又加上唯一限制,然后再加上索引以供查询使用。事实上,MySQL 的唯一限制和主键限制都是通过索引实现的,因此,上面的写法实际上在相同的列上创 建了三个重复的索引。通常并没有理由这样做,除非是在同一列上创建不同类型的索引 来满足不同的查询需求。 冗余索引和重复索引有一些不同。如果创建了索引(A B),再创建索引(A)就是冗余索 引,因为这只是前一个索引的前缀索引。因此索引(AB)也可以当作索引(A)来使用(这种 冗余只是对B-Tree索引来说的)。但是如果再创建索引 (B,A),则不是冗余索引,索引 (B)也不是,因为B不是索引(A,B)的最左前缀列。 已有的索引(A),扩展为(A,ID),其中ID是主键,对于InnoDB来说主键列已经包含在二 级索引中了,所以这也是冗余的。解决冗余索引和重复索引的方法很简单,删除这些索引就可以,但首先要做的是找出这 样的索引。可以通过写一些复杂的访问INFORMATION_SCHEMA表的查询来找。 删除未使用的索引 除了冗余索引和重复索引,可能还会有一些服务器永远不用的索引。这样的索引完全是 累赘,建议考虑删除。 补充资料:磁盘和B+树 为什么关系型数据库都选择了B+树,这个和磁盘的特性有着非常大的关系。 如果我们简化一下,可以这么看 一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁 盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不 能转动,但是可以沿磁盘半径方向运动。 盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁 道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁 盘的最小存储单元也是最小读写单元。现在磁盘扇区一般是512个字节~4k个字节。 磁盘上数据必须用一个三维地址唯一标示:柱面号、盘面号、扇区号。 读/写磁盘上某一指定数据需要下面步骤: (1)  首先移动臂根据柱面号使磁头移动到所需要的柱面上,这一过程被称为定位或查找。 (2)所有磁头都定位到磁道上后,这时根据盘面号来确定指定盘面上的具体磁道。 (3) 盘面确定以后,盘片开始旋转,将指定块号的磁道段移动至磁头下。 经过上面步骤,指定数据的存储位置就被找到。这时就可以开始读/写操作了。可以看见,磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三 个部分耗时相加就是一次磁盘IO的时间,一般大概9ms左右。寻道时间(seek)是将读写磁头 移动至正确的磁道上所需要的时间,这部分时间代价最高;旋转延迟时间(rotation)是磁盘 旋转将目标扇区移动到读写磁头下方所需的时间,取决于磁盘转速;数据传输时间 (transfer)是完成传输数据所需要的时间,取决于接口的数据传输率,在纳秒级,远小于前 两部分消耗时间。磁盘读取时间成本是访问内存的几百倍到几万倍之间。 为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每 次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据 放入内存,这个称之为预读。这样做的理论依据是计算机科学中著名的局部性原理: 当一个数据被用到时,其附近的数据也通常会马上被使用。 程序运行期间所需要的数据通常比较集中。 大家可以试运行下面这段代码:    public static void main(String[] args) {         int[][] arr = new int[10000][10000];         int sum = 0;         long startTime = System.currentTimeMillis();         for (int i = 0; i < arr.length; i++) {              for (int j = 0; j < arr[0].length; j++) {                   /*按行访问数组*/                   sum += arr[i][j];              }        }         System.out.println("按行耗时:" + (System.currentTimeMillis() - startTime) + "ms");         sum = 0;         startTime = System.currentTimeMillis();         for (int i = 0; i < arr.length; i++) {              for (int j = 0; j < arr[0].length; j++) {                   /*按列访问数组*/                   sum += arr[j][i];              }         }         System.out.println("按列耗时:" + (System.currentTimeMillis() - startTime) + "ms");    } 就能看到局部性原理对程序性能的影响。 由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),一般来说,磁盘的 顺序读的效率是随机读的40到400倍都有可能,顺序写是随机写的10到100倍(SSD盘则差距 要小的多,顺序读写的效率是随机读写的7到10倍,但是有评测表明机械硬盘的顺序写性能稍 优于SSD。总的来说Mysql数据库如果由硬盘由机械的换成SSD的,性能会有很大的提升), 因此对于具有局部性的程序来说,预读可以提高I/O效率。 预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往 往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页,页大小通常为4k当 然也有16K的,主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发 一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取 一页或几页载入内存中,然后异常返回,程序继续运行。 按照磁盘的这种性质,如果是一个页存放一个B+树的节点,自然是可以存放很多的数据的,比 如InnoDB里,默认定义的B+树的节点大小是16KB,这就是说,假如一个Key是8个字节,那 么一个节点可以存放大约1000个Key,意味着B+数可以有1000个分叉。同时InnoDB每一次磁 盘I/O,读取的都是 16KB的整数倍的数据。也就是说InnoDB在节点的读写上是可以充分利用 磁盘顺序IO的高速读写特性。 同时按照B+树逻辑结构来说,在叶子节点一层,所有记录的主键按照从小到大的 顺序排列,并且形成了一个双向链表。同一层的非叶子节点也互相串联,形成了一 个双向链表。那么在实际读写的时候,很大的概率相邻的节点会放在相邻的页上, 又可以充分利用磁盘顺序IO的高速读写特性。所以我们对MySQL优化的一大方向 就是尽可能的多让数据顺序读写,少让数据随机读写。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/2401_85327573/article/details/144309075

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

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

相关文章

文字稿 | MatrixOne2.0.0:AI向量与高可用能力的重磅升级MatrixOne 2.0.0 新特性解读

MatrixOne 2.0.0 是一款 AI 驱动的云原生超融合数据库&#xff0c;采用了存算分离的架构&#xff0c;全面优化了云上资源利用效率。 MatrixOne兼容 MySQL 协议和语法&#xff0c;具备支持混合负载场景的能力&#xff0c;并结合向量数据类型、全文检索等特性&#xff0c;为生成式…

Qt Xlsx安装教程

Qt Xlsx安装教程 安装perl 如果没有安装perl&#xff0c;请参考perl Window安装教程 下载QtXlsxWriter源码 下载地址 ming32-make编译32 lib库 C:\Qt\Qt5.12.12\5.12.12\mingw73_32>d: D:\>cd D:\Code\QtXlsxWriter-master\QtXlsxWriter-master D:\Code\QtXlsxWrit…

记一次js Long类型精度丢失问题

背景&#xff1a; 微信小程序和后端springboot后端服务联调&#xff0c;用户id是19位的数值型&#xff0c;通过postman工具调用没有精度问题&#xff0c;小程序调用用户id和后端返回的不一致。 解决办法 网上文章很多&#xff0c;自行搜索吧&#xff0c; 这是站内的一个博客&…

【49】AndroidStudio构建其他人开发的Android项目

(1)做Android软件开发&#xff0c;通常会看一些其他人开发的项目源码&#xff0c;当将这些项目的源码通过git clone到本地之后&#xff0c;用AndroidStudio进行打开时&#xff0c;通常会遇到一些环境配置的问题。本文即用来记录在构建他人开发项目源代码这一过程中遇到的一些常…

day08 接口测试(3)——postman工具使用

下载 postman 的历史版本&#xff1a;Postman 历史版本下载 - 简书 我自己根据我的电脑&#xff0c;安装的地址为&#xff1a;https://dl.pstmn.io/download/version/9.31.32/osx_64 今天开始学习 postman 这个测试工具啦。 【没有所谓的运气&#x1f36c;&#xff0c;只有绝…

OpenCV相机标定与3D重建(10)眼标定函数calibrateHandEye()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算手眼标定&#xff1a; g T c _{}^{g}\textrm{T}_c g​Tc​ cv::calibrateHandEye 是 OpenCV 中用于手眼标定的函数。该函数通过已知的机器人…

Thinkphp6 模型软删除注意点

模型软删除异常 当在model use SoftDelete; 并配置了相关软删除字段和类型后&#xff0c;模型就支持软删除了。但是当执行delete方法后&#xff0c;会发现软删除异常&#xff0c;没有正在执行删除&#xff0c;只执行了一下sql: SHOW FULL COLUMNS FROM tb_xxxx;正确方法是&am…

vue中显示 .tif 图片

1、安装 tiff cnpm install tiff.js2、main.js 引入 import Tiff from tiff.js;<template><canvas id"tiff-canvas" style"width: 200px; height: auto;"></canvas> </template> <script> export default {mounted(){this…

day08 接口测试(4)知识点完结!!

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、postman读取外部数据文件&#xff08;参数化&#xff09; 1.1 数据文件简介 1.2 导入外部数据文件 1.2.1 csv文件 1.2.2 导入 json文件 1.3 读取数据文件数据 1.4 案例 1.5 生成测试报告 2、小…

linux 安装 Jenkins 教程

前言 Jenkins 是一个开源的自动化服务器&#xff0c;广泛用于持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;和持续交付&#xff08;Continuous Delivery&#xff0c;CD&#xff09;领域。它帮助开发者自动化软件构建、测试、部署等过程&#xff0c;从…

鸿蒙高级开发者认证的主观题试题及答案

以下是一份鸿蒙高级开发者认证的主观题试题及答案示例,涵盖了鸿蒙开发中的多个关键技术和应用场景相关内容,希望对你有所帮助: 一、论述题(每题 20 分,共 60 分) 1. 阐述鸿蒙操作系统中分布式软总线的工作原理、核心优势以及在多设备协同应用开发场景下的应用方式,并举…

IdentityServer4框架、ASP.NET core Identity

OAuth2.0 IdentityServer4 官网 中文官网 ASP.NET Core Identity提供了一个用来管理和存储用户账户的框架. IdentityServer4是基于ASP.NET Core实现的认证和授权框架&#xff0c;是对OpenID Connect和OAuth 2.0协议的实现。 IdentityServer是一个中间件,它可以添加符合OpenID…

ZZCMS2023存在跨站脚本漏洞(CNVD-2024-44822、CVE-2024-44818)

ZZCMS是一款用于搭建招商网站的CMS系统&#xff0c;由PHP语言开发&#xff0c;可快速搭建&#xff1a;医药招商、保健品招商、化妆品招商、农资招商、孕婴童招商、酒类副食类等招商网站。 国家信息安全漏洞共享平台于2024-11-14公布其存在跨站脚本漏洞。 漏洞编号&#xff1a…

使用Kubernetes部署MySQL+WordPress

目录 前提条件 部署MySQL和WordPress 编写yaml文件 应用yaml文件 存在问题及解决方案 创建PV(持久化卷) 创建一个PVC(持久化卷声明) 部署添加PVC 查看PV对应的主机存储 删除资源 查看资源 删除deployment和service 查看主机数据 删除PVC和PV 删除主机数据 前提条…

每日一刷——12.10——学习二叉树解题模式(二)

题目三&#xff1a;填充每个节点的下一个右侧节点指针1 题目描述&#xff1a;116. 填充每个节点的下一个右侧节点指针 - 力扣&#xff08;LeetCode&#xff09; 我的理解&#xff1a; 我的感觉是同父亲还好搞一点&#xff0c;感觉是在遍历到每一个节点的时候&#xff0c;就把…

Spring Cloud Alibaba:一站式微服务解决方案

Spring Cloud Alibaba介绍 在当今的软件开发领域&#xff0c;微服务架构因其灵活性、可扩展性和独立性等优势而备受青睐。Spring Cloud Alibaba 作为一款强大的一站式微服务解决方案&#xff0c;为开发者提供了丰富的工具和组件&#xff0c;帮助他们轻松构建和管理复杂的微服务…

服务器数据恢复—LINUX下各文件系统删除/格式化的数据恢复可行性分析

Linux操作系统是世界上流行的操作系统之一&#xff0c;被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统&#xff08;EXT2/EXT3/EXT4/Reiserfs/Xfs&#xff0…

vs打开unity项目 新建文件后无法自动补全

问题 第一次双击c#文件自动打开vs编辑器的时候能自动补全&#xff0c;再一次在unity中新建c#文件后双击打开发现vs不能自动补全了。每次都要重新打开vs编辑器才能自动补全&#xff0c;导致效率很低&#xff0c;后面发现是没有安装扩展&#xff0c;注意扩展和工具的区别。 解决…

网络安全-态势感知

0x00 定义&#xff1a; 态势感知&#xff08;Situation Awareness&#xff0c;SA&#xff09;能够检测出超过20大类的云上安全风险&#xff0c;包括DDoS攻击、暴力破解、Web攻击、后门木马、僵尸主机、异常行为、漏洞攻击、命令与控制等。利用大数据分析技术&#xff0c;态势感…

命令模式的理解和实践

在软件开发中&#xff0c;设计模式是开发者们经过长期实践总结出来的、可复用的解决方案&#xff0c;用于解决常见的设计问题。命令模式&#xff08;Command Pattern&#xff09;是行为型设计模式之一&#xff0c;它通过将一个请求封装成一个对象&#xff0c;从而允许用户用不同…