前段时间项目中,使用到了mysql中的find_in_set 查询,因为原先没有使用过此方法,故进行了些许研究。

如mysql官方文档所说,find_in_set (str ,  strlist) 函数,查询字段(strlist)中包含 str 的结果,return 为 符合的结果 或者  null。举例如下:

select * from  (select 1,2,3,'1,2,3' as strlist) as table1 where find_in_set('1',strlist);
返回如下:

另外一种情况:

select * from  (select 1,2,3,'1,2,3' as strlist) as table1 where find_in_set('0',strlist);
结果如下:


经过测试,已经可以看到使用like查询是可以获取到同样结果的。而mysql中也有这样的解释:find_in_set 是精确匹配,字段值以英文 ‘,’ 分隔,而like 是广泛的模糊查询,字段中无需使用分隔符。可以说,两者使用的情景不一样,不过,看到这突然想到两者的查询方式是有何区别呢?于是使用真实的表进行了一下测试:

因find_in_set检测的字段需要使用英文逗号分隔,所以创建sql如下:

SELECT id FROM `consumer` WHERE find_in_set('hoftime',company);      
SELECT id FROM `consumer` WHERE company like ',hoftime,';
结果如下:



由上图可看到,取出的结果集是有相同部分的,原因很简单,like 查询没有使用通配符,而数据存储是无序的,所以单纯使用like查询是只能获取单纯的数据,find_in_set 会全局精确匹配。那么这就有了另外一个想法,那就是,find_in_set 以及 like ‘%%’ 两者那一个比较优质呢?使用explain观察sql执行顺序,以上面的sql为基础,修改查询添加索引的字段,测试如下:

explain SELECT id FROM `consumer` WHERE find_in_set('13888888888',mobile);

explain SELECT id FROM `consumer` WHERE mobile like ',13888888888,';

添加一个等同于第一条的sql,即like'%%'方式(结果与find_in_set一致):

explain SELECT id FROM `consumer` WHERE mobile like '%,13888888888,%';


由此可以看出,查询结果一致的情况下,或者必须使用like‘%%’的情况下,二者任选其一即可,这个作用场景适合字段中以英文逗号分隔的查询语句。如果没有逗号分隔,虽然都可以获取到同样的数据,但那样的话,使用like查询会更友好一些,毕竟like'str ',like'str%' 等都能够使用索引,而同样使用find_in_set 即使能够获取到想要的数据,成本也太高了。





Logo

更多推荐