`
小小龙猫
  • 浏览: 98390 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于 find_in_set 的性能问题

阅读更多

同事不少数据表设计的时候使用一个字段来存储多对多关系,比如 表 user中有一个字段叫 category, category存储的是 "1,3,9" 这样的类型的数据,实际上是category的id 用逗号分隔开来的。

 

要查询一个用户属于id为2分类的用户可以这么写

 

 

select * from `user` where find_in_set('2',`user`.`category`)

 

具体find_in_set 的使用请参照手册

http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set

 

 

虽然这样很好用,但问题是如果数据量大的情况下怎么办,性能会是问题么,手册上有说对find_in_set 做的优化,但在没有索引的情况下他的性能应该是个问题。

 

于是做了个测试,user 表录入 100万的数据,同时建立 user_category 表,每个user有 3 个分类,那么category表里有300万条记录。

 

CREATE TABLE `user_category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `category_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `category_id` (`category_id`),
  KEY `user_id` (`tax_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT 

 

 

现在比较一下在百万级的数据量上使用 join 链接外键查询和find_in_set查询的性能

 

1. 使用 find_in_set 查询,平均时间在2.2秒左右

 

 

SELECT SQL_NO_CACHE COUNT(*) FROM `user` WHERE FIND_IN_SET(65,category)
 

 

 

2. 使用left join , 使用了右表中的索引,平均时间在0.2秒左右

 

SELECT SQL_NO_CACHE COUNT(DISTINCT(`user`.id)) FROM `user` 
LEFT JOIN `user_category` ON `user`.`id`= `user_category`.`user_id`
WHERE `user_category`.`category_id`=75

 

 

所以在大数据量的情况下还是不适合用find_in_set, 不过有些表的数据可能永远就那么点数据,这个时候为了减少表数量,倒是可以用这样的方法做。

分享到:
评论

相关推荐

    Mysql中FIND_IN_SET()和IN区别简析

    性能方面,`IN` 通常优于 `FIND_IN_SET()`。特别是当查询的字段是主键或具有索引时,`IN` 可以利用索引来快速定位符合条件的行,从而提高查询速度。相反,`FIND_IN_SET()` 无法利用索引,因此在大数据集上可能会导致...

    MySQL高效模糊搜索之内置函数locate instr position find_in_set使用详解

    为了提高效率,MySQL提供了几个内置的模糊搜索函数:`LOCATE`、`INSTR`、`POSITION`以及`FIND_IN_SET`。这些函数在某些情况下比`LIKE`操作更快,尽管它们都无法利用索引来加速查询。 1. **`LOCATE()`** 函数: - ...

    Mysql中的find_in_set的使用方法介绍

    `IN`可以更好地利用索引,对于大数据量和复杂查询来说,性能通常优于`FIND_IN_SET`。 如果你对`FIND_IN_SET`的顺序排序有兴趣,可以使用`FIND_IN_SET`结合`ORDER BY`来实现,但这需要额外的计算步骤。同时,如果你...

    MySQL的FIND_IN_SET函数使用方法分享

    MySQL的FIND_IN_SET函数是一种专门用来在字符串列表中搜索特定项的位置的函数。这个函数在处理那些将多个分类或标签以逗号分隔的形式存储在一个字段中的情况时非常有用,例如文章表中的`type`字段,它可能包含了如"1...

    mysql通过find_in_set()函数实现where in()顺序排序

    为了解决这个问题,我们可以利用`FIND_IN_SET()`函数来实现按指定顺序排序。`FIND_IN_SET()`函数是MySQL提供的一种特殊功能,它在字符串列表中搜索指定的元素并返回其位置(1为基础)。 `FIND_IN_SET(str, strlist)...

    PostgreSQL_8.2.3.rar_postgresql_windows 8

    在“PostgreSQL_8.2.3_中文文档.chm”中,我们可以找到关于PostgreSQL 8.2.3的详细中文指南。CHM文件是Microsoft的 Compiled HTML Help 文件,它以电子书的形式提供了一整套的文档和帮助信息,便于用户快速查询和...

    MySql逗号拼接字符串查询的两种方法

    `FIND_IN_SET`函数会检查第二个字符串是否包含第一个字符串中的任意一个元素,而`FIND_PART_IN_SET`则是在传入的第一个字符串(如'1,3,6')中的任意一个元素存在于第二个字符串(如'1,2,3,4,5')中时返回1,表示匹配...

    完美解决mysql in条件语句只读取一条信息问题的2种方案

    此外,值得注意的是,使用`FIND_IN_SET()`函数可能会对性能产生一定影响,因为它不能利用索引,尤其是在处理大量数据时。因此,如果可能,最佳做法是避免在数据库中存储逗号分隔的列表,而是采用关联表来存储多对多...

    PHP程序设计-3期(KC016) 5.2.2删除数据拓展知识.doc

    本节将深入探讨PDO(PHP Data Objects)扩展在删除MySQL数据库中的数据,特别是关于批量删除和使用`find_in_set()`函数的方法。 PDO是PHP提供的一种面向对象的数据库访问接口,支持多种数据库系统,包括MySQL。使用...

    PHP程序设计-3期(KC016) 5.2.2删除数据常见问题.docx

    然而,需要注意的是,`FIND_IN_SET`并不是一个高效的查询方式,当`bookId`列表非常长时,可能会导致性能下降。因此,如果可能,更推荐使用`IN`操作符配合预处理语句的变通方法,如使用多个占位符或者将数组拆分成多...

    find_path4.cpp.zip_The Point

    “find the the set point in which triangle in the mesh”描述的算法可能包括以下几个步骤: 1. **预处理**:首先,需要对网格进行预处理,构建数据结构以有效地存储和查询三角形。这可能包括使用空间划分数据...

    MySQL递归查询树状表的子节点、父节点具体实现

    接着,使用`FIND_IN_SET`函数查询所有父节点ID包含在`sChildTemp`中的记录,将这些记录的ID通过`GROUP_CONCAT`函数合并成新的`sChildTemp`。循环结束后,返回`sChildList`作为结果。 调用方式: - `select ...

    Mysql select in 按id排序实现方法

    针对MySQL,有两个函数可以帮助我们解决这个问题:`FIND_IN_SET`和`SUBSTRING_INDEX`。 1. **FIND_IN_SET** 函数: `FIND_IN_SET(str, strlist)` 函数在字符串`strlist`中查找子字符串`str`的第一次出现的位置。`...

    将MySQL查询结果按值排序的简要教程

    `FIND_IN_SET`在处理`SET`类型字段时会被优化,但在常规字符串字段上使用可能会导致性能下降,因为它需要遍历整个字符串列表。如果排序字段的值是动态的,这种方法可能导致全表扫描,效率较低。 另外,如果需要按照...

    MySQL 存储过程传参数实现where id in(1,2,3,...)示例

    总结起来,MySQL存储过程通过`FIND_IN_SET()`函数或动态构建SQL语句的方式,能够灵活地处理`WHERE ID IN`的筛选条件。这种技术在处理大量数据或者需要动态条件时非常有用,但也需要注意安全问题。在实际应用中,应该...

    MySQL Like语句的使用方法

    6. `FIND_IN_SET`与`IN()`的区别: `IN()`函数用于检查某个值是否在一组值中,对于简单列表,`IN()`可能更有效率。但是,当`pingid`是一个包含逗号分隔值的字符串时,`FIND_IN_SET`更适合。 总的来说,`LIKE`、`...

    MySQL 存储过程传参数实现where id in(1,2,3,…)示例

    总的来说,理解如何在MySQL存储过程中处理参数化的`WHERE ID IN`查询,以及何时使用`FIND_IN_SET`或动态SQL,是优化数据库操作的关键技能。同时,应关注性能、安全性和代码的可读性,以实现高效且可靠的数据库解决...

Global site tag (gtag.js) - Google Analytics