访问方法access method---单表访问方法(三十六)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 访问方法access method---单表访问方法(三十六)

上篇文章回忆了innodDB的独立表空间和系统表空间的结构,因为需要梳理的知识点太多,所以额外用一篇。

独立表空间&系统表空间总结---innoDB表空间(三十五)


单表的访问方法


对我们开发来说,mysql就是个软件,用sql查询我们需要的数据,当遇到性能差的sql,如果我们连怎么优化都不知道,岂不是很尴尬。我们前面说过mysqlSql Service 有一个查询优化器的模块,一条sql进行预发解析后会进行查询优化,生成一个执行计划,这个执行计表明有哪些索引进行查询,表之间的链接顺序是什么样的,最后调用执行计划的步骤来真正的查询,吧结果返回给用户。不过查询优化这里的信息有点大,我们这里先看看单表的访问方法(from 单表那种)。


访问方法(access method)的概念


举个例子,大家用地图找路线的时候 ,地图会给你好几种路线,甚至你可以选择吧中国绕一遍再去到目的地,但不论哪种路线,你都能去到目的地,只是耗费的时间不同。回到mysql,我们只要获取到自己的需要的数据,至于mysql优化器怎么优化成执行计划查出来,是mysql的事。对于单表查询,mysql大致分为两种:

  1. 使用全表扫描进行查询:这种顾名思义,为了查询数据,吧整个表都遍历一遍,基本算是最笨的方法,但什么数据都能找到。
  2. 使用索引进行查询:因为使用全表扫描的方法代价太大,所以可以查询搜索语句中加入索引查询,使用索引查询又分为,1)针对主键或者唯一二级索引的等值查询。2)针对普通二级索引的等值查询。3)针对索引列的范围查询。4)直接扫描整个索引。

Mysql吧这种查询语句的方式称为访问方法或者访问类型。同一个sql语句可能有多种不同的查询方法,但查询的结果都是一样的。下面介绍各自方法的具体内容。

先建立个表single_table,给他五个索引,id为主键索引,key1和key3为普通索引,key2为唯一索引,idx_key_part为联合索引。然后自己可以写个程序给他插入10000条数据。

mysql> create table single_table(
    ->  id int not null auto_increment,
    ->  key1 varchar(100),
    ->  key2 int,
    ->  key3 varchar(100),
    ->  key_part1 varchar(100),
    ->  key_part2 varchar(100),
    ->  key_part3 varchar(100),
    ->  common_field varchar(100),
    ->  primary key(id),
    ->  key idx_key1 (key1),
    ->  unique key idx_key2 (key2),
    ->  key idx_key3 (key3),
    ->  key idx_key_part(key_part1,key_part2,key_part3)
    -> 
    -> )engine=innoDB charset=utf8;
Query OK, 0 rows affected (0.10 sec)


Const


当用主键查询和用唯一二级索引查询的时候,查询的是const方式,这种方式表示速度非常快,性能消耗基本忽略不计,为什么呢?

SELECT * FROM single_table WHERE id = 1438;
SELECT * FROM single_table WHERE key2 = 3841;

我们前面说了主键查询是直接在聚簇索引的b+树叶子节点上查询的,聚簇索引叶子节点存放的是当前列的所有数据,所以只要直接查询就可以获取所有数据。

当我们用唯一二级索引查询的时候,最多也就回表查询一次,因为二级索引的叶子几点存放的是对应的id,再用id回表从聚簇索引b+树查询一次。

至于唯一的二级索引比较特殊,比如这样:

SELECT * FROM single_table WHERE key2 IS NULL;

因为唯一二级索引并不限制null值的数量,所以导致可能查询多条数据,这样sql优化机制就没办法就const方法来进行查询。


ref


上面的情况是唯一二级索引查询,那如果普通二级索引查询呢?

SELECT * FROM single_table WHERE key1 = 'abc';

这时候,速度就是ref,比const效率差一点点,因为普通二级索引没有唯一性,可能会查询来多条数据,所以并不能根主键查询和唯一二级索引那样效率更高,前面的如果是坐火箭的话,这里大概是坐高铁差不多。查询的数据主要还是要看在二级索引的叶子节点会查出多少条id,如果id太多,回表的频率高,就非常影响性能,如果回表次数少,那效率还是非常高的。

1、二级索引列为null的情况:这点唯一二级索引和普通二级索引都一样,因为null可能存在多条,这种情况最多效率就是ref。

2、对于那种联合索引的二级索引来说,必须是where语句后面跟着常树相等的参数,比如

SELECT * FROM single_table WHERE key_part1 = 'god like'; SELECT * FROM single_table WHERE key_part1 = 'god like' AND key_part2 = 'legendary'; SELECT * FROM single_table WHERE key_part1 = 'god like' AND key_part2 = 'legendary' AND key_part3 = 'penta kill';

效率就是ref方法访问数据库,

如果是这种,则就不能达到ref方法访问数据库的效率。

SELECT * FROM single_table WHERE key_part1 = 'god like' AND key_part2 > 'legendary';


ref_or_null


当我们查询索引加null值的sql:

SELECT * FROM single_table WHERE key1 = 'abc' OR key1 IS NULL;

当这种情况,我们通过查询null值,并且这个sql没走全表扫描的时候,大部分is null都会放弃索引进行全表扫描,因为索引里没有存储null,如果这里走的是索引查询,则是用ref_or_null访问数据库。


range


这种区间方法查询数据库,如下sql会发生:

SELECT * FROM single_table WHERE key2 IN (1438, 6328) OR (key2 >= 38 AND key2 <= 79);

当前查询的区间是,1438数据和6328数据,以及38~79之间,这些数据都是sql需要的,这个sql可以用全表查询,或者二级索引+回表查询,此时查询就不是对某一个常量来匹配了,而是对这是哪个区间进行匹配。

1438和6328为单点范围区间,而38~79为连续范围区间,这种在mysql里面是用range方法来查询数据库的。


index


接下来看这个sql:

SELECT key_part1, key_part2, key_part3 FROM single_table WHERE key_part2 = 'abc';

这个sql特点是他们都属于联合索引,联合索引的特点是后面的如果查询使用到索引,必须最左边那个数据是相等的,简称最左原则,所以这里并不能用range和ref方法区查询数据库。

但这里他可以通过遍历二级联合索引,来查询我们所需要的值,并且这里前面需要查询的数据,都在二级叶子节点里,所以并不需要回表去聚簇索引叶子节点查询。


all


这种是性能最差的全表查询,大家在写sql时候尽量避免这种方法访问数据库。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
8月前
|
人工智能 自然语言处理 搜索推荐
“AI拜年”火遍朋友圈,营销的终局是拼技术
2025年春节前夕,AI拜年成为新潮流。百度通过“春节祝福语”活动,利用文心大模型4.0 Turbo生成个性化拜年贺卡,用户只需上传照片和输入文案,即可获得高度逼真的定制贺卡。这项技术凭借iRAG(检索增强生成)实现了高精度图像生成,避免了常见的“AI味儿”,使AI生成的内容既真实又富有文化内涵,为普通用户带来了专业级的创作体验,也为图像生成的产业化落地铺平了道路。
261 9
|
10月前
|
存储 关系型数据库 MySQL
智能调度、秒级弹性|一文带你探索Compaction Service的进化之路
ADB MySQL的Compaction Service功能通过将Compaction任务从存储节点解耦至独立的弹性资源池执行,解决了资源隔离性弱、并发度低等问题,实现了资源消耗降低50%,任务执行时间平均减少40%,并支持按量付费,提升了系统的稳定性和成本效益。
|
Linux
centos如何安装libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg
centos如何安装libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg
1618 0
|
机器学习/深度学习 人工智能 监控
人工智能在金融风险管理中的应用
人工智能在金融风险管理中的应用已经取得了显著的进展,并在提高风险管理效率和准确性方面发挥了重要作用。通过信用评估、欺诈检测、投资组合管理等应用,人工智能为金融行业带来了新的机遇和挑战。然而,我们也要认识到人工智能在风险管理中可能面临的隐私、解释性和偏差等问题。未来,随着技术的发展,人工智能将在金融领域持续发挥重要作用,为金融行业创造更加安全和稳健的环境。
1204 1
|
3天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1091 0
|
12天前
|
人工智能 运维 安全
|
2天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
399 9
|
11天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。
|
3天前
|
弹性计算 Kubernetes jenkins
如何在 ECS/EKS 集群中有效使用 Jenkins
本文探讨了如何将 Jenkins 与 AWS ECS 和 EKS 集群集成,以构建高效、灵活且具备自动扩缩容能力的 CI/CD 流水线,提升软件交付效率并优化资源成本。
278 0
|
10天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!