当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL JSON_OVERLAPS 什么条件下能使用多值索引

MySQL JSON_OVERLAPS 什么条件下能使用多值索引

来源:17golang原创 2026-10-06 22:34:50 0浏览 收藏

我遇到过一种很容易误判的情况:索引已经创建成功,查询也确实写了 JSON_OVERLAPS(),但 EXPLAIN 仍然显示全表访问。关键不在函数名本身,而在存储引擎、JSON 数组表达式、查询路径和候选数组类型是否能对上。

官方文档:https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html

要点速览
  • MySQL 的多值索引面向 JSON 数组,JSON_OVERLAPS() 只表示“至少一个元素相交”。
  • 索引通常写成 CAST(json_path AS 类型 ARRAY),查询左侧要使用同一 JSON 数组路径。
  • 是否真的采用索引,要看 EXPLAIN 中的 key、type 和预计行数,而不是看建索引语句是否成功。

一、先分清 JSON_OVERLAPS 的相交语义

JSON_OVERLAPS(a, b) 对数组执行的是 OR 关系:两边只要共享一个数组元素就返回 1。它和 JSON_CONTAINS() 的“候选数组全部存在”不是一回事。例如筛选“标签包含任意一个目标标签”时,重叠查询才符合语义;如果要求所有标签都命中,应先重新确认业务条件,不能只为了用索引改函数。

-- 只要 zipcode 数组与目标数组有一个元素相同,就命中
SELECT id, custinfo
FROM customers
WHERE JSON_OVERLAPS(
  custinfo->'$.zipcode',
  CAST('[94507, 94582]' AS JSON)
);

另外,JSON 比较不会把数字字符串自动当成数字。索引数组是数值时,候选数组也要保持数值类型;"94507" 与 94507 不能按同一个数组元素理解。

二、把 JSON 数组表达式建成多值索引

多值索引的核心不是给整个 JSON 文档做一个普通键,而是把一行中的数组拆成多个索引记录。下面的表达式把 zipcode 数组中的元素转换为无符号整数数组,再建立名为 zips 的索引:

-- JSON 路径要指向数组;UNSIGNED 要与数组元素的实际类型一致
ALTER TABLE customers
  ADD INDEX zips(
    (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY))
  );
MySQL JSON 数组路径经过 CAST ARRAY 生成多值索引元素键的结构说明图
图1:多值索引结构说明图,查看 JSON 数组表达式如何拆成可检索的元素键。

因此至少要同时满足这几个条件:

检查项应满足的条件不满足时的表现
表引擎InnoDB不能按该路径获得多值索引优化
索引表达式合法 JSON 表达式 + CAST(... AS ... ARRAY)无法形成对应的数组元素键
查询路径与索引中的数组路径一致索引可能不在候选键中
元素类型索引类型与候选 JSON 数组类型一致结果可能不命中或无法按预期优化

三、保持查询路径和索引路径一致

索引建在 custinfo->'$.zipcode',查询左侧就不要换成另一个路径,也不要在外层包一层无法匹配的表达式。候选数组使用 JSON 文档形式显式转换,便于保持类型和语义清楚:

-- 右侧是 JSON 数组;OVERLAPS 表示任意一个 zipcode 相交即可
EXPLAIN SELECT id
FROM customers
WHERE JSON_OVERLAPS(
  custinfo->'$.zipcode',
  CAST('[94507, 94582]' AS JSON)
);

如果业务实际上是“同时包含 94507 和 94582”,这个查询仍然只要求命中其中一个。此时应考虑 JSON_CONTAINS() 的 AND 语义,并重新观察它的执行计划,不能把“有索引”和“语义正确”混成一件事。

四、用 EXPLAIN 判断是否真的使用索引

我排查这类问题时只看四个字段:possible_keys 表示候选索引,key 表示最终选择,type 反映访问方式,rows 是优化器估算需要检查的行数。官方示例中,建立 zips 后,JSON_OVERLAPS() 查询可以呈现 type=range 且 key=zips 的计划。

MySQL JSON_OVERLAPS 查询通过 EXPLAIN 核对 possible_keys、key、type 和 rows 的判断说明图
图2:EXPLAIN 判断说明图,沿着查询条件核对 possible_keys、key 和访问类型。
-- 先看优化器是否把 zips 放进候选并最终选中
EXPLAIN
SELECT id, custinfo
FROM customers
WHERE JSON_OVERLAPS(
  custinfo->'$.zipcode',
  CAST('[94507, 94582]' AS JSON)
);

判断可以按下面的清单进行:

  • key=zips:本次计划最终选中了多值索引。
  • possible_keys 有 zips 但 key=NULL:索引可用但成本模型没有选择它,先检查选择性和估算统计信息。
  • type=ALL 且 key=NULL:当前计划是全表访问,优先核对路径、类型、存储引擎和索引定义。
  • rows 很大:即使使用了索引,也要结合返回列、过滤比例和实际数据分布判断收益。

五、按数据形态排查不生效和边界

空数组不会产生多值索引条目,所以它不能通过索引扫描被找到;数组中的 JSON null 也不是普通 SQL NULL,建立或维护索引时可能触发无效 JSON 值错误。先把这些数据清洗规则固定下来,再决定索引是否值得保留。

多值索引还不能作为覆盖索引,也不支持排序、范围扫描或索引前缀;复合索引最多放一个多值键部分。它适合解决“按数组成员快速找行”,不适合顺便完成排序或只从索引返回全部列。

最后,别把“能使用”理解成“每次都会使用”。MySQL 优化器仍会比较成本。上线前至少准备三组计划:无索引、索引存在但路径不匹配、路径和类型都匹配;分别记录 key 与 rows,这样遇到数据量变化时才知道是语义问题、定义问题还是成本选择问题。

相关问题

JSON_OVERLAPS 能保证两个数组全部相同吗?

不能。它只判断是否至少有一个元素或键值对相交;“全部包含”要使用不同的查询语义。

看到 possible_keys=zips 就代表已经走索引吗?

不代表。possible_keys 只是候选集合,最终应看 key;如果是 NULL,还要结合成本估算解释原因。

多值索引能同时解决 ORDER BY 吗?

不能把它当排序索引使用。它主要服务于 JSON 数组成员的过滤,排序和覆盖查询要另行设计。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go sync.OnceFunc 包装的函数 panic 后再次调用会怎样Go sync.OnceFunc 包装的函数 panic 后再次调用会怎样
上一篇
Go sync.OnceFunc 包装的函数 panic 后再次调用会怎样
Go Reader 返回 n 大于零和 EOF 时应该先处理哪个
下一篇
Go Reader 返回 n 大于零和 EOF 时应该先处理哪个
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    354次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    414次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    422次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    377次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    199次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码