MySQL之创建高性能的索引(七)

news2024/11/18 11:19:49

创建高性能的索引

InnoDB和MyISAM的数据分布对比

聚簇索引和非聚簇索引欸度数据分布有区别,以及对应的主键索引和二级索引的数据分布也有区别,通常会让人感到困扰和意外。来看看InnoDB和MyISAM时如何存储下面这个表的:

CREATE TABLE layout_test (
col1 INT NOT NULL,
col2 INT NOT NULL,
PRIMARY KEY ( col1 ),
KEY ( col2 )
);

假设该表的主键取值为1~10 00,按照随机顺序插入并使用OPTIMIZE TABLE命令做了优化。换句话说,数据在磁盘上的存储方式已经是最优,但行的顺序是随机的。列col2的值是从1~100之间随机复制,所以有很多重复的值。
在这里插入图片描述

MyISAM的数据分布

MyISAM的数据分布非常简单。MyISAM按照数据插入的顺序存储在磁盘上,如图所示。在行的旁边显式了行号,从0开始递增。因为行是定长的,所以MyISAM可以从表的开头跳过所需的字节找到需要的行(MyISAM并不总是使用上图中的"行号",而是根据定长还是变长的行使用不同策略)。这种分布方式很容易创建索引。下面显式的一系列图,隐藏了页的物理细节,只显示索引中的"节点",索引中的每个叶子节点包含"行号"。如图所示显式了表的主键。这里忽略了一些细节,例如前一个B-Tree节点有多少个内部节点,不过这并不影响对非聚簇存储引擎的基本数据分布的理解,
那么col2l列上的索引又会如何呢?有什么特殊的吗?回答是否定的:它和其他的所以没有什么区别,如图所示显示了col2列上的索引.事实上,MyISAM中主键索引和其他索引在结构上没有什么不同,主键索引就是一个名为PRIMARY的唯一非空索引。

  • MyISAM表layout_test的主键分布在这里插入图片描述
  • MyISAM表layout_test的col2列索引的分布
    在这里插入图片描述

InnoDB的数据分布

因为InnoDB支持聚簇索引,所以使用非常不同的方式存储同样的数据。InnoDB以如图所示的方式存储数据。
第一眼看上去,感觉该图和前面的图没有什么区别,但再仔细看细节,会注意道该图显示了整个表,而不是只有索引。因为在InnoDB中,聚簇索引"就是"表,所以不像MyISAM那样需要独立的行存储。聚簇索引的每一个叶子节点都包含了主键值、事务ID、用于事务和MVCC的回滚指针以及所有的剩余列(在这个例子中是col2).如果主键是一个列前缀索引,InnoDB也会包含完整的主键列和剩下的其他列。

还有一点和MyISAM的不同是,InnoDB的二级索引和聚簇索引很不相同。InnoDB二级索引的叶子节点中存储的不是"行指针",而是主键值,并以此作为指向行的"指针"。这样的策略减少了当出现行移动或者数据页分裂时二级索引的维护工作。使用主键值当作指针会让二级索引占用更多的空间,换来的好处是,InnoDB在移动时无须更新二级索引中的这个"指针".

如图所示,显示了示例表的col2索引。每一个叶子节点都包含了索引列(这里是col2),紧接着是主键值(col1).该图展示了B-Tree的叶子节点结构,但我们故意省略了非叶子节点这样的细节,InnoDB的非叶子节点包含了索引列和一个指向下级节点的指针(下一级节点可以是非叶子节点,也可以是叶子节点)。这对聚簇索引和二级索引都适用。

下图是描述InnoDB和MyISAM如何存放表的抽象图。从图中可以很容易看出InnoDB和MyISAM保存数据和索引的区别

  • InnoDB表layout_test的主键分布在这里插入图片描述
  • InnoDB表layout_test的二级索引分布
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在InnoDB表中按主键顺序插入行

如果正在适用InnoDB并且没有什么数据需要聚集,那么可以定义一个代理键(surroagte key)作为主键,这种主键的数据应该和应用无关,最简单的方法是适用AUTO_INCREMENT自增列。这样可以保证数据行是按顺序写入,对于根据主键作关联操作的性能也会更好。最好避免随机的(不连续且值得分布范围非常大)聚簇索引,特别是对于IO密集型得应用。例如,如果从性能得考虑,适用UUID来作为聚簇索引则会很操作:它使得聚簇索引得插入变得完全随机,这是最坏得情况,使得数据没有任何聚集特性

CREATE TABLE userinfo (
id int unsigned NOT NULL AUTO_INCREMENT,
name varchar(64) NOT NULL DEFAULT '',
email varchar(64) NOT NULL DEFAULT '',
password varchar(64) NOT NULL DEFAULT '',
dob date DEFAULT NULL,
address varchar(255) NOT NULL DEFAULT '',
city varchar(64) NOT NULL DEFAULT '',
state_id tinyint unsigned NOT NULL DEFAULT '0',
zip varchar(8) NOT NULL DEFAULT '',
country_id smallint unsigned NOT NULL DEFAULT '0',
account_type varchar(32) NOT NULL DEFAULT '',
verfied tinyint NOT NULL DEFAULT '0',
allow_email tinyint unsigned NOT NULL DEFAULT '0',
parrent_account int unsigned NOT NULL DEFAULT '0',
closest_airport varchar(3) NOT NULL DEFAULT '',
PRIMARY KEY(id),
UNIQUE KEY email(email),
KEY country_id (country_id),
KEY state_id(state_id),
KEY state_id_2(state_id,city,address)
) ENGINE=InnoDB;

注意到使用了自增的整数ID作为主键。
第二个例子是user_info表,除了主键改为UUID,其余和上面的userinfo表完全相同。

CREATE TABLE userinfo_uuid(
uuid varchar(36) NOTNULL,
....

首先,要在一个有足够内存容纳索引的服务器上向这两个表各插入100万条记录,然后向这两个表继续插入300万条记录,使索引的大小超过服务器的内存容量。测试结果如图.注意到向UUID主键插入行不仅花费的时间更长,而且索引占用的空间也更大。这一方面是由于主键字段更长;另一方面毫无疑问是由于页分裂和碎片导致的。为了明白为什么会这样,来看看往第一个表种插入数据时,索引发生了什么变化。如图所示了插满一个页面后继续插入相邻的下一个页面的场景。如图所示,因为主键的值是顺序的,所以InnoDB把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB默认的最大填充因子是页大小的15/16,留出部分空间用于以后修改),下一条记录就会写入新的页种。一旦数据按照这种顺序的方式加载,主键页就会近似于被顺序的记录填满,这也正是所期望的结果(然而,二级索引页可能是不一样的)。
对比一下向第二个使用了UUID聚簇索引的表插入数据,看看有什么不同,如图所示。因为新行的主键值不一定比之前插入的大,所以InnoDB无法简单地总是把新行插入到索引的最后,而是需要为新的行寻找合适的位置——通常是已有数据的中间位置——并且分配空间。这会增加很多的额外工作,并导致数据分布不够优化。下面是总结的一些缺点:

  • 1.写入的目标页可能已经刷到磁盘上并从缓存种移除,或者是还没有被加载到缓存中,InnoDB在插入之前不得不先找到并从磁盘读取目标页到内存种。这将导致大量的随机IO
  • 2.因为写入是乱序的,InnoDB不得不频繁地做页分裂操作,以便为新地行分配空间。页分裂会导致移动大量数据,一次插入最少需要修改三个页而不是一个页
  • 3.由于频繁的页分裂,页会变得稀疏并被不规则地填充,所以最终数据会有碎片。
    把这些随机值载入到聚簇索引以后,也需要做一次OPTIMIZE TABLE来重建表并优化页的填充。从这个案例可以看出,使用InnoDB时应该尽可能地按逐渐顺序插入数据,并且尽可能地使用单调递增的聚簇键的值来插入新行
    在这里插入图片描述
  • 向聚簇索引插入顺序的索引值在这里插入图片描述
  • 向聚簇索引种插入无序的值
    在这里插入图片描述

顺序的主键什么时候会造成更坏的结果?

对于高并发工作负载,在InnoDB中按主键顺序插入可能会造成明显的争用。主键的上界会成为"热点"。因为所有的插入都发生在这里,所以并发插入可能导致间隙锁竞争。另一个热点可能是AUTO_INCREMENT锁机制;如果遇到这个问题,则可能需要考虑重新设计表或者应用,或者更改innodb_autoinc_lock_mode配置。如果你的服务器版本还不支持innodb_autoinc_lock_mode参数,可以升级到新版本的InnoDB,可能对这种场景工作得更好

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

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

相关文章

R语言ggplot2包绘制世界地图

数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 1. 数据读取与处理 首先&#xff0c;从CSV文件中读取数据&#xff0c;并计算各国每日收入的平均签证成本。 library(tidyverse) ​ df <- read_csv("df.csv") %>% group_…

自监督表示学习和神经音频合成实现语音修复

关键词&#xff1a;语音修复、自监督模型、语音合成、语音增强、神经声码器 语音和/或音频修复的目标是增强局部受损的语音和/或音频信号。早期的工作基于信号处理技术&#xff0c;例如线性预测编码、正弦波建模或图模型。最近&#xff0c;语音/音频修复开始使用深度神经网络&a…

用万界星空科技低代码平台能快速搭建一个云MES系统

一、低代码平台与MES:智能制造的新篇章 随着工业4.0和智能制造的兴起&#xff0c;企业对于生产过程的数字化、智能化需求日益迫切。传统的MES系统实施周期长、成本高&#xff0c;成为许多企业数字化转型的瓶颈。而低代码开发平台的出现为这一问题提供了新的解决思路。 二、万界…

Linux常用环境Docker安装

一、mysql安装 简单安装 docker run -d \--name mysql \-p 3306:3306 \-e TZAsia/Shanghai \-e MYSQL_ROOT_PASSWORD123 \mysql mysql容器本地挂载 cd /usr mkdir mysql cd mysql/ mkdir data mkdir conf mkdir init可以手动导入自己的数据库信息 docker run -d \--name mys…

MES系统的功能、架构及应用价值

MES系统生产过程控制的主要方面涵盖了生产计划与控制、生产调度与排程、数据采集与监控、质量控制与管理、物料管理与控制以及设备管理与维护等多个方面。这些功能共同构成了MES系统的核心价值&#xff0c;帮助企业实现生产过程的数字化、智能化和精细化管理。 一、工厂使用MES…

Opera 浏览器与Google联手,推出由Gemini驱动的全新AI功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

JavaScript 动态网页实例 —— 窗口控制

除了打开和关闭窗口之外,还有很多其他控制窗口的方法。例如,可以使用 window.focus()方法使窗口获得焦点,也可以利用与其相对的window.blur 方法使窗口失去焦点。本节介绍移动窗口、改变窗口大小、窗口滚动、窗口超时操作、常用窗口事件、常用窗口扩展等窗口控制的方法和手段。…

AI办公自动化:用通义千问Qwen-Long批量总结PDF长文档内容

Qwen-Long是在通义千问针对超长上下文处理场景的大语言模型&#xff0c;支持中文、英文等不同语言输入&#xff0c;支持最长1000万tokens(约1500万字或1.5万页文档)的超长上下文对话。配合同步上线的文档服务&#xff0c;可支持word、pdf、markdown、epub、mobi等多种文档格式的…

HCIP-Datacom-ARST自选题库__BGP/MPLS IP VPN判断【10道题】

1.部署BGP/MPLSIP VPN时,当两个VPN有共同的站点,则该共同站点一定不能与两个VPN其他站点使用重叠的地址空间。 2.如图所示&#xff0c;运营商BGP/MPLSIP VPN骨干网通过LDP构建LSP&#xff0c;若想实现用户X两个站点之间通过BGP/MPLSIP VPN网络互通&#xff0c;则PE1和PE2之间必…

大规模 Transformer 模型 8 比特矩阵乘

本文基于 Hugging Face Transformers、Accelerate 以及 bitsandbytes库。 Transformers&#xff1a;Hugging Face 提供的一个开源库&#xff0c;包含了多种预训练的 Transformer 模型&#xff0c;方便用户进行各种 NLP 任务。Accelerate&#xff1a;Hugging Face 开发的一个库…

【STM32】定时器与PWM的LED控制

目录 一、定时器控制LED周期性亮灭&#xff08;一&#xff09;定时器1.STM32F103定时器分类及区别2.通用定时器主要功能3.通用定时器工作过程 &#xff08;二&#xff09;STM32CubeMX创建工程&#xff08;三&#xff09;代码实现&#xff08;四&#xff09;实验结果 二、PWM模式…

7.1 Go 错误的概念

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

富士摄像机X-H2S MOV格式化后重新写入后的恢复方法

X-H2S是富士数码的一款旗舰机型&#xff0c;支持4K/6K高清&#xff0c;视频编码为最新的HVC。下面我们来看下富士数码摄像机恢复案例。 故障存储:512G存储卡 Exfat文件系统 故障现象: 512G的卡误格式化后又进行了拍摄&#xff0c;卡使用了120G不到的空间&#xff0c;其它底…

深入分析 Android Service (五)

文章目录 深入分析 Android Service (五)1. 深入分析 Service 与 Activity 之间的通信2. Messenger 的内部工作原理2.1 服务端实现2.2 客户端实现 3. AIDL 的内部工作原理3.1 定义 AIDL 接口3.2 服务端实现3.3 客户端实现 4. Service 的优化建议和最佳实践4.1 异步操作4.2 资源…

Vite项目构建chrome extension,实现多入口

本项目使用Vite5 Vue3进行构建。 要使用vite工程构建浏览器插件&#xff0c;无非就是要实现popup页面和options页面。这就需要在项目中用到多入口打包&#xff08;生成多个html文件&#xff09;。 实现思路&#xff1a; 通过配置vite工程&#xff0c;使得项目打包后有两个h…

每天学点小知识:WSL安装Ubuntu 22.04 LTS

前言 本章教会你在不使用虚拟机下使用linux&#xff0c;但是这里建议还是使用虚拟机&#xff0c;或者装一双系统&#xff0c;wsl使用linux还是有很多问题的。 1. 简介WSL WSL&#xff08;Windows Subsystem for Linux&#xff09;是微软为Windows 10及以上版本开发的一项功能…

如何在IDEA中实现类似Linux命令那样的外部传参

【背景说明】 IDEA中执行一个程序时&#xff0c;如何就在程序一开始执行给传入你给的参数呢&#xff1f; 【说明】 public static void main(String[] args) throws Exception {} 说明&#xff1a;其实java中main方法里的args这个参数&#xff0c;就是用于接收外部传参的。…

注意力机制详解

引言 在阅读一篇文章时&#xff0c;我们的大脑并不平等地处理每一个字词&#xff0c;而是根据上下文自动筛选出核心信息进行深入理解。注意力机制正是借鉴了这一生物学灵感&#xff0c;使得机器学习模型能够动态地分配其“注意力”资源&#xff0c;针对不同的输入部分赋予不同…

R语言ggplot2包绘制网络地图

重要提示&#xff1a;数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 载入R包 rm(listls()) pacman::p_load(tidyverse,assertthat,igraph,purrr,ggraph,ggmap) 网络节点和边数据 nodes <- read.csv(nodes.csv, row.names 1) edges…

6个PPT素材模板网站,免费!

免费PPT素材模板下载&#xff0c;就上这6个网站&#xff0c;建议收藏&#xff01; 1、菜鸟图库 ppt模板免费下载|ppt背景图片 - 菜鸟图库 菜鸟图库是一个设计、办公、媒体等素材非常齐全的网站&#xff0c;站内有几百万的素材&#xff0c;其中PPT模板就有几十万个&#xff0c;…