Mysql中FIND_IN_SET函数的具体使用

 更新时间:2026年07月24日 09:45:34   作者:探索未知的自己  
本文深入解析FIND_IN_SET函数的用法、场景与性能陷阱,告诉你为什么它无法使用索引,并分享实用的优化替代方案,帮你避开全表扫描的坑,提升查询效率

FIND_IN_SET 是 MySQL 的一个字符串处理函数,用于在逗号分隔的字符串列表中查找指定值的位置。

一、函数语法

FIND_IN_SET(str, strlist)
参数说明
str要查找的字符串
strlist逗号分隔的字符串列表(如 'A,B,C')

返回值:

  • 如果找到,返回 位置(从 1 开始)
  • 如果没找到,返回 0
  • 如果 str 或 strlist 为 NULL,返回 NULL

二、基本示例

SELECT FIND_IN_SET('B', 'A,B,C,D');   -- 返回 2
SELECT FIND_IN_SET('Z', 'A,B,C,D');   -- 返回 0
SELECT FIND_IN_SET(NULL, 'A,B,C,D');  -- 返回 NULL
SELECT FIND_IN_SET('B', NULL);        -- 返回 NULL
SELECT FIND_IN_SET('B', '');          -- 返回 0

三、常见使用场景

1. 判断某个值是否在逗号分隔的字符串中

-- 查询所属系统包含 '1' 的记录
SELECT * FROM vehicle 
WHERE FIND_IN_SET('1', belonging_system) > 0;

2. 按逗号分隔字符串排序

-- 按用户指定的顺序排序(如 3,1,2)
SELECT * FROM user 
ORDER BY FIND_IN_SET(id, '3,1,2');

3. 结合 COALESCE 处理 NULL

-- 如果参数为 NULL,查询全部;否则按 IN 匹配
SELECT * FROM vehicle 
WHERE (?1 IS NULL OR FIND_IN_SET(?1, belonging_system) > 0);

4. 统计某个值出现的次数

-- 统计 VIN 中包含 'L58' 的记录数
SELECT COUNT(*) FROM vehicle 
WHERE FIND_IN_SET('L58', vin) > 0;

四、在你的场景中使用 FIND_IN_SET

场景:belonging_system 是逗号分隔的字符串

-- 查询 belonging_system 包含 systemId 的所有记录
SELECT * FROM vehicle 
WHERE FIND_IN_SET('1', belonging_system) > 0;

-- 结合参数判空
SELECT * FROM vehicle 
WHERE (?1 IS NULL OR FIND_IN_SET(?1, belonging_system) > 0);

JPA 原生查询写法

@Query(value = "SELECT * FROM vehicle v " +
       "WHERE (COALESCE(?1, NULL) IS NULL OR FIND_IN_SET(?1, v.belonging_system) > 0)", 
       nativeQuery = true)
Page<Vehicle> findBySystemId(@Param("systemId") String systemId, Pageable pageable);

五、FIND_IN_SET vs IN

对比项FIND_IN_SETIN
适用场景字段是逗号分隔的字符串字段是单个值
用法FIND_IN_SET('A', column) > 0column IN ('A', 'B')
索引使用❌ 无法使用索引✅ 可以使用索引
性能全表扫描,数据量大时慢有索引时快
参数传递传单个字符串需要传多个值(集合)

核心区别:

  • IN 用于多个值的列表匹配
  • FIND_IN_SET 用于单个字段中存储的逗号分隔字符串匹配

六、性能注意事项

⚠️ FIND_IN_SET 无法使用索引,在数据量大时性能较差。

数据量性能表现
< 1 万条✅ 可以接受
1 万 ~ 10 万⚠️ 可能变慢
> 10 万❌ 严重性能问题

优化建议

  • 改用关联表(推荐)

    • 将 belonging_system 从逗号分隔字符串改为多对多关联表
    • 使用 IN 或 EXISTS 查询,利用索引
  • 使用 JSON 数组(MySQL 5.7+)

    -- 存储为 JSON 数组
    SELECT * FROM vehicle 
    WHERE JSON_CONTAINS(belonging_system, '"1"');
  • 使用全文索引

    ALTER TABLE vehicle ADD FULLTEXT(belonging_system);
    SELECT * FROM vehicle 
    WHERE MATCH(belonging_system) AGAINST('1');

七、完整示例

-- 1. 基本查找
SELECT FIND_IN_SET('2', '1,2,3,4');  -- 返回 2

-- 2. 在 WHERE 中使用
SELECT * FROM user WHERE FIND_IN_SET('admin', roles) &gt; 0;

-- 3. 结合 ORDER BY(按指定顺序)
SELECT * FROM product 
WHERE id IN (3,1,2) 
ORDER BY FIND_IN_SET(id, '3,1,2');

-- 4. 结合 CASE
SELECT 
    name,
    CASE 
        WHEN FIND_IN_SET('admin', roles) &gt; 0 THEN '管理员'
        WHEN FIND_IN_SET('user', roles) &gt; 0 THEN '普通用户'
        ELSE '未知'
    END AS role_name
FROM user;

八、总结

要点说明
功能在逗号分隔的字符串中查找值的位置
返回值找到返回位置(1-based),没找到返回 0
主要场景判断值是否存在于逗号分隔字段中
优点简单直观,适合小数据量
缺点无法使用索引,大数据量时性能差
替代方案关联表、JSON 数组、全文索引

建议:如果 belonging_system 经常被查询,建议改为多对多关联表,彻底解决性能问题。如果数据量小(< 1 万),FIND_IN_SET 可以接受。

到此这篇关于Mysql中FIND_IN_SET函数的具体使用的文章就介绍到这了,更多相关Mysql FIND_IN_SET内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • M1芯片安装mysql8.0数据库的实现步骤(图文)

    M1芯片安装mysql8.0数据库的实现步骤(图文)

    这篇文章主要介绍了M1芯片安装mysql8.0数据库的实现实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 使用use index优化sql查询的详细介绍

    使用use index优化sql查询的详细介绍

    本篇文章是对使用use index优化sql查询进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL时间溢出原理、影响与解决方案

    MySQL时间溢出原理、影响与解决方案

    本文将手把手带您了解mysql时间溢出原理、实战影响与全面解决方案,所有代码均通过dblens for mysql数据库工具验证,推荐使用该工具进行可视化数据库管理和开发,感兴趣的小伙伴跟着小编一起来看看吧
    2025-03-03
  • Mysql 分批加索引的详细方法

    Mysql 分批加索引的详细方法

    文章主要介绍了在生产环境中为千万级数据表分批次创建索引的策略和方法,包括使用临时表、分区表、ONLINE选项、分批ALTER TABLE、pt-online-schema-change工具等,并提供了详细的步骤和注意事项,感兴趣的朋友一起看看吧
    2024-12-12
  • 基于Mysql+JavaSwing的超市商品管理系统设计与实现

    基于Mysql+JavaSwing的超市商品管理系统设计与实现

    本项目是使用Java swing开发,可实现超市管理系统商品列表信息查询、添加商品信息和修改商品管理以及删除商品信息和安装商品信息查询等功能。界面设计和功能比较简单基础、适合作为Java课设设计以及学习技术使用,需要的朋友可以参考一下
    2021-09-09
  • MySQL之初始化数据详解

    MySQL之初始化数据详解

    本文介绍了MySQL命令行的基本操作,包括列出数据库、创建数据库、使用数据库、查看表、删除数据库、退出MySQL等,还详细介绍了数据库表的结构和属性,以及如何创建和初始化测试数据
    2025-01-01
  • Django创建项目+连通mysql的操作方法

    Django创建项目+连通mysql的操作方法

    这篇文章主要介绍了Django创建项目+连通mysql的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • MySQL MHA 高可用集群搭建过程详解

    MySQL MHA 高可用集群搭建过程详解

    MHA 是一套优秀的、开源的 MySQL 高可用性解决方案,它的核心目标是在 MySQL 主从复制环境中,实现主库故障时的自动故障转移和快速切换,尽可能保证数据库服务的连续性,这篇文章主要介绍了MySQL MHA 高可用集群搭建指南,需要的朋友可以参考下
    2025-10-10
  • MySQL 互为主备的实现教程

    MySQL 互为主备的实现教程

    本文主要介绍了MySQL 互为主备的实现教程,包括正确编辑my.ini配置文件、确保数据库操作前置条件完成以及避免在关键步骤中修改数据库数据,以确保配置成功
    2026-06-06
  • MYSQL 没有完全卸载将导致其安装不成功

    MYSQL 没有完全卸载将导致其安装不成功

    安装MYSQL不成功,一般是因为服务器可能安装过MYSQL而没有完全卸载。
    2009-06-06

最新评论