MySQL 单表访问方法详解

embedded/2025/2/23 22:49:18/

单表访问

  • MySQL 单表访问方法详解:高效查询之道
      • **一、 查询执行基础**
      • **二、 访问方法 (Access Method) 概念**
      • **三、 具体访问方法 (从最优到最差)**
      • **四、 注意事项**
      • **五、 总结与优化建议**
      • **六、 电商网站数据存储应用示例**
      • **七、 数据备份与恢复模型 (补充)**

MySQL 单表访问方法详解:高效查询之道

核心思想: MySQL 执行单表查询的目标是尽可能高效地从表中获取所需数据。访问方法(Access Method)决定了 MySQL 如何扫描表中的记录,是全表扫描还是利用索引,直接影响查询性能。理解并选择合适的访问方法是查询优化的基础。

一、 查询执行基础

  • 查询优化器****与执行计划: MySQL Server 中的查询优化器解析查询语句后生成执行计划。执行计划决定了使用哪些索引、表的连接顺序等。存储引擎根据执行计划执行查询并返回结果。理解查询执行原理是优化慢查询的关键。

  • 单表查询: 本文聚焦于单表查询(FROM 子句后只有一个表),这是最基础的查询类型。

二、 访问方法 (Access Method) 概念

访问方法是指 MySQL 访问表数据的方式,决定了查询优化器选择哪种策略检索数据。

  • 全表扫描 (ALL): 逐行扫描所有记录。适用于无索引或查询条件无法利用索引的情况,效率低,尤其对于大表。

  • 索引访问: 利用索引快速定位数据。包括针对主键/唯一索引的等值查询、普通二级索引的等值查询、索引列的范围查询以及索引全扫描等。

三、 具体访问方法 (从最优到最差)

以下访问方法按效率从高到低排序,类似于查询优化器选择路径的优先级:

  1. const (或 system):常数级别访问
  • 原理: 使用主键 (PRIMARY KEY) 或唯一二级索引 (UNIQUE INDEX) 与常数进行等值匹配,且最多返回一条记录。systemconst 的特例,表只有一行记录时使用。

  • 机制: B+ 树索引快速查找,直接定位。由于索引的有序性,查找接近 O(1)。查询优化器预先计算索引查找路径。

  • 应用场景: 根据用户 ID (主键) 查用户信息;根据唯一订单号 (唯一索引) 查订单。

  • 性能: 极速,少量 I/O。

  • 示例:


SELECT * FROM users WHERE id = 1; -- id 是主键SELECT * FROM orders WHERE order_no = 'unique_123'; -- order_no 是唯一索引

限制 :仅适用于主键列或唯一二级索引列与常数的等值比较,且当唯一二级索引列值为 NULL 时不可用此方法。

  1. eq_ref:唯一索引等值引用 (连接查询)
  • 原理: 连接查询中,被驱动表通过主键或唯一二级索引等值匹配访问,且保证对于驱动表的每条记录,被驱动表最多只返回一条匹配记录。

  • 机制: 索引关联,驱动表结果驱动被驱动表查询。被驱动表通过唯一索引快速查找。

  • 应用场景: 订单表和用户表关联,通过用户 ID (用户表主键) 关联订单表;一对一关联。

  • 性能: 高效,少量 I/O。

  • 示例:


SELECT o.*, u.* FROM orders o JOIN users u ON o.user_id = u.id WHERE o.order_id = 100; -- users.id 是主键
  1. ref:非唯一索引等值引用
  • 原理: 使用非唯一二级索引进行等值匹配,可能返回多条记录。

  • 机制: 索引范围扫描,找到多条索引记录。ref 是等值匹配 ( =, IN),range 是范围匹配 (>, <, BETWEEN)。

  • 应用场景: 根据商品分类 ID (非唯一索引) 查商品;根据用户角色 (非唯一索引) 查用户。

  • 性能: 比全表扫描高效,但不如 consteq_ref

  • 示例:


SELECT * FROM products WHERE category_id = 5; -- category_id 是非唯一索引

注意事项 :若二级索引列值为 NULL,只能使用 ref 访问方法而非 const;对于联合索引,只要最左边的连续索引列与常数等值比较就可能采用 ref 方法,否则不能称为 ref。

  1. fulltext:全文索引
  • 原理: 查询条件涉及MATCH AGAINST语法,且使用全文索引。

  • 机制: 基于倒排索引,将文本拆分成词语并记录。支持相关性排序(如 TF-IDF 或 BM25)。

  • 应用场景: 商品搜索(根据名称、描述);博客文章搜索(根据标题、内容)。

  • 性能: 针对文本搜索优化,比LIKE '%keyword%'效率高。

  • 示例:


SELECT * FROM articles WHERE MATCH(title,content) AGAINST ('MySQL 优化');
  1. ref_or_null:索引等值引用或 NULL
  • 原理: 类似于 ref,但多了对 NULL 值的处理。查询条件是索引列等值匹配 + IS NULL

  • 机制: 先索引等值查找 (同 ref),再扫描索引的 NULL 值记录。索引列需允许 NULL。

  • 应用场景: 查询非必填字段为特定值或为空的记录。

  • 性能: 略低于 ref

  • 示例:


SELECT * FROM users WHERE email = 'test@example.com' OR email IS NULL; -- email 有索引且允许 NULL
  1. index_merge:索引合并
  • 原理: 一个表可以使用多个索引完成查询,MySQL 将多个索引扫描结果合并。

  • 机制: 优化器判断可使用多个索引分别过滤,合并结果 (Intersection, Union, Sort-Union)。

  • index_merge_intersection: 索引求交集 (AND)。

  • index_merge_union: 索引求并集 (OR)。

  • index_merge_sort_union: 先排序,再求并集。

  • 应用场景: 复杂查询条件,可使用多个索引独立过滤。

  • 性能: 通常优于全表扫描,但取决于索引选择性和合并策略。不当使用可能比单个索引低效。

  • 示例:

Intersection 合并 示例:查询 single_table 表中 key1 = ‘a’ AND key3 = ‘b’ 的记录,可使用 idx_key1 和 idx_key3 索引进行 Intersection 合并。此外,主键列可进行范围匹配的情况也可使用此合并方法。

Union 合并 示例:查询 single_table 表中 key1 = ‘a’ OR key3 = ‘b’ 的记录,可使用 idx_key1 和 idx_key3 索引进行 Union 合并。

Sort-Union 合并 示例:查询 single_table 表中 key1 < ‘a’ OR key3 > ‘z’ 的记录,可使用 idx_key1 和 idx_key3 索引进行 Sort-Union 合并。


SELECT * FROM products WHERE price < 100 OR category_id = 5; -- price 和 category_id 都有索引

联合索引替代索引合并 :在可能的情况下,使用联合索引可替代索引合并,提高查询效率。例如查询 single_table 表中 key1 = ‘a’ AND key3 = ‘b’ 的记录,可通过创建联合索引 idx_key1_key3(key1, key3) 来直接使用联合索引查询,避免索引合并操作。

  1. range:索引范围扫描
  • 原理: 使用索引进行范围查询 (BETWEEN, >, <, IN, OR 等)。

  • 机制: 索引有序性,定位范围起止,扫描范围内的索引记录。可处理复杂范围条件。

  • 应用场景: 查询价格范围内的商品;查询时间段内的订单;IN 列表查询。

  • 性能: 比全表扫描高效,但范围越大,效率越低。

  • 示例:


SELECT * FROM products WHERE price BETWEEN 50 AND 100;SELECT * FROM orders WHERE order_date >= '2023-01-01' AND order_date < '2023-02-01';

范围区间确定 :对于复杂搜索条件,需分析哪些条件可使用同一索引,并确定该索引对应的范围区间。如多个条件通过 AND 连接,取各条件范围区间的交集;通过 OR 连接则取并集。若部分条件无法使用索引,则在确定范围区间时将其替换为 TRUE。

  1. index:索引全扫描
  • 原理: 扫描整个索引树,但只需要索引中的列数据。

  • 机制: 遍历索引树。索引通常比数据表小且有序,index 比全表扫描快。常发生在 “覆盖索引” 情况。

  • 应用场景: 统计记录数 (索引包含所有行);查询只需要索引列数据。

  • 性能: 比全表扫描快,但仍需扫描整个索引,低于 range

  • 示例:

定义 :当查询列表中的列全部包含在某个二级索引中,且查询条件仅涉及该索引列时,可直接遍历二级索引记录获取结果,无需回表操作。因二级索引记录较小,且避免了回表开销,查询效率较高。


SELECT COUNT(*) FROM orders; -- 若优化器选择索引扫描SELECT order_id FROM orders; -- order_id 是主键或有索引
  1. ALL:全表扫描
  • 原理: 无法使用索引,扫描所有记录。

  • 机制: 逐行读取,检查是否满足条件。效率最低。

  • 应用场景: 表很小;查询条件无法使用索引 (无索引,或索引失效)。

  • 性能: 极低,尤其对于大表,应避免。

  • 示例:


SELECT * FROM products WHERE description LIKE '%keyword%'; -- description 无索引或前导模糊匹配

四、 注意事项

  • 二级索引+回表: 一般,查询只能用单个二级索引。优化器选扫描行数少的二级索引查询,再回表获取完整记录,根据剩余条件过滤。例如:SELECT * FROM single_table WHERE key1 = 'abc' AND key2 > 1000;,可能先用idx_key1定位key1 = 'abc',再回表根据key2 > 1000过滤。

五、 总结与优化建议

  • 索引是关键: 高效访问方法多依赖索引。合理创建和使用索引是核心。

  • 避免全表扫描: ALL 通常是性能瓶颈。尽量优化查询,使用索引。

  • 使用 EXPLAIN 分析 SQL 执行计划,看 MySQL 选择的访问方法,判断是否高效,及如何优化。

  • 关注索引类型和选择性: 不同索引 (B-tree, Hash, Fulltext) 适用不同场景。索引选择性 (区分度) 越高越好。

  • 优化 SQL: 编写高效 SQL,避免索引失效 (如索引列上用函数)。

六、 电商网站数据存储应用示例

  • const 用户登录,根据用户名 (唯一索引) 和密码 (通常不直接索引,但用户名唯一索引可快速定位)。

  • eq_ref 订单详情,订单表关联订单项表,通过订单 ID (订单项表外键,订单表主键)。

  • ref 商品分类,根据分类 ID (非唯一索引) 查询商品。

  • range 商品价格筛选,查询价格范围内的商品。

  • fulltext: 商品搜索功能。

  • index / ALL (需优化避免): 报表统计,若设计不当可能全表扫描或索引全扫描,需索引优化和查询改写。

七、 数据备份与恢复模型 (补充)

数据备份与恢复虽非直接访问方法,但保证数据安全和可用性,间接提升访问效率。

  • 备份策略:

  • 逻辑备份 (Logical Backup): 导出 SQL (如 mysqldump),灵活但慢。

  • 物理备份 (Physical Backup): 复制数据文件 (如 MySQL Enterprise Backup, Xtrabackup),快但灵活性低。

  • 全量备份 (Full Backup): 备份所有数据。

  • 增量备份 (Incremental Backup): 备份上次全量/增量备份后变化的数据。

  • 差异备份 (Differential Backup): 备份上次全量备份后变化的数据。

  • 恢复策略:

  • 完全恢复: 恢复到备份时间点。

  • 时间点恢复 (with Binary Logs): 结合备份和二进制日志,恢复到任意时间点。

  • 备份模型选择: 根据数据重要性、RTO、RPO、存储空间等选择。核心业务数据库通常采用物理全量 + 增量 + 二进制日志。

总结: 数据备份与恢复保证数据安全和可用性,是数据库稳定运行的基础。定期备份和恢复演练是 DBA 的重要职责。


http://www.ppmy.cn/embedded/164693.html

相关文章

IDEA CodeGPT 使用教程

IDEA CodeGPT 使用教程 CodeGPT 是一个 IntelliJ IDEA 插件&#xff0c;可以利用 OpenAI&#xff08;或自建 AI 模型&#xff09;来帮助开发者完成代码编写、优化、调试、解释错误等任务。以下是详细的安装与配置教程。 1. 安装 CodeGPT 插件 方式 1&#xff1a;从插件市场安…

尝试在exo集群下使用deepseek模型:第一步,调通llama

exo是一个多机协同AI大模型集群软件&#xff0c;它可以将多种设备统一成一个强大的GPU&#xff0c;支持多种模型&#xff0c;并具有动态模型分区、自动设备发现等功能‌。 问题 实践&#xff1a;多机协同AI大模型集群软件exo&#xff1a;体验github日榜第一名的魅力&#xff…

【进程 】

【进程】 目录1. ELF格式程序与进程2. 进程的组织方式3. 进程的复刻&#xff08;fork&#xff09;4. 进程的状态 目录 1. ELF格式程序与进程 在Linux系统里&#xff0c;程序文件普遍采用ELF&#xff08;Executable and Linkable Format&#xff09;格式。这种格式的程序文件存…

Linux-GlusterFS进阶分布式卷

文章目录 创建分布式卷创建复制卷 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年02月19日19点30分 创建分布式卷 同样是在Node1上进行的操作 分布式卷中的文件只能放在一个brick里…

私有化项目管理平台搭建:基于Leantime的实战经验分享

文章目录 前言1.关于Leantime2.本地部署Leantime3.Leantime简单实用4.安装内网穿透5.配置Leantime公网地址6. 配置固定公网地址 前言 本文主要介绍如何在本地Linux系统使用Docker部署Leantime&#xff0c;并结合cpolar内网穿透工具轻松实现随时随地查看浏览器页面&#xff0c;…

Webpack 基础入门

一、Webpack 是什么 Webpack 是一款现代 JavaScript 应用程序的静态模块打包工具。在 Web 开发中&#xff0c;我们的项目会包含各种类型的文件&#xff0c;如 JavaScript、CSS、图片等。Webpack 可以将这些文件打包成一个或多个文件&#xff0c;以便在浏览器中高效加载。它就像…

华为guass在dbever和springboot配置操作

下面记录华为guass在dbever和springboot配置操作&#xff0c;以备忘。 1、安装dbeaver-ce-23.2.0-x86_64-setup.exe和驱动程序 Download | DBeaver Community 2、配置高斯数据库驱动 3、新建数据库连接 4、操作指引 opengauss官方文档 https://docs-opengauss.osinfra.cn/zh…

qt for android release apk 手动签名方式

window 下&#xff0c;打开cmd 安装android sdk相关配置后&#xff0c;进行下列步骤 1.获取密钥&#xff0c; keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000根据提示步骤&#xff0c;输入密钥口令&…