对于mysql的like查询,我想都会很熟悉,对于一些基本查询也会常用,但始终不是对大数据量查询的方案。在查询数据需要对某一个字段里的值当作条件时,一般会用到like、instr()、find_in_set(),首先看一下手册里对这3种用法的定义。
expr LIKE pat [ESCAPE ‘escape-char’]
模式匹配,使用SQL简单正规表达式比较。返回1 (TRUE) 或 0 (FALSE)。 若 expr 或 pat 中任何一个为 NULL,则结果为 NULL。
模式不需要为文字字符串。例如,可以被指定为一个字符串表达式或表列。
在模式中可以同LIKE一起使用以下两种通配符:
字符 说明
% 匹配任何数目的字符,甚至包括零字符
_ 只能匹配一种字符
FIND_IN_SET(str,strlist)
假如字符串str 在由N 子链组成的字符串列表strlist 中, 则返回值的范围在 1 到 N 之间 。一个字符串列表就是一个由一些被‘,’符号分开的自链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。 这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
INSTR(str,substr)
返回字符串 str 中子字符串的第一个出现位置。这和LOCATE()的双参数形式相同,除非参数的顺序被颠倒。
然后来实际操作一次,有以下一下这样的一个数据。
data:
+------+----------------+ | id | tagsid | +------+----------------+ | 4 | 2863,4351,4353 | | 3 | | | 5 | 3395,2219 | | 6 | | | 8 | | | 9 | | | 10 | 2689,4349,2863 | | 1652 | | | 12 | 4347,3161,3029 | | 13 | 2193,2519,2229 | +------+----------------+ 10 rows in set (0.00 sec)
首先我们使用like查询,结果如下:
mysql> select id,tagsid from tbl_news where find_in_set('2863',`tagsid`) limit 1 0; +-----+--------------------------+ | id | tagsid | +-----+--------------------------+ | 4 | 2863,4351,4353 | | 10 | 2689,4349,2863 | | 78 | 2863,2197,4327 | | 245 | 3395,2863 | | 85 | 2863,2497,3869,4315 | | 108 | 2193,4301,2863,4303 | | 121 | 4277,2863,4279,3311,3215 | | 122 | 4277,4279,2863,4189,3109 | | 137 | 3361,3811,2829,3255,2863 | | 149 | 2289,2197,2863,2519,4199 | +-----+--------------------------+ 10 rows in set (0.00 sec)
注意:
select id,tagsid from tbl_news where find_in_set(字段,值) limit 10;
使用find_in_set函数一次返回多条记录
mysql> select id,tagsid from tbl_news where find_in_set(`id`,'78,10,21,2,3,22') limit 10;
id 是一个表的字段 然后每条记录分别是id等于78,10,21,2,3,22的时候,有点类似in (集合)。
mysql> select id,tagsid from tbl_news where `id` in(78,10,21,2,3,22) limit 10;
然后用find_in_set()查询,结果如下:
mysql> select id,tagsid from `tbl_news` limit 10; +------+----------------+ | id | tagsid | +------+----------------+ | 4 | 2863,4351,4353 | | 3 | | | 5 | 3395,2219 | | 6 | | | 8 | | | 9 | | | 10 | 2689,4349,2863 | | 1652 | | | 12 | 4347,3161,3029 | | 13 | 2193,2519,2229 | +------+----------------+ 10 rows in set (0.00 sec)
最后使用instr()查询,结果如下:
mysql> select id,tagsid from tbl_news where instr(`tagsid`,'2863') > 0 limit 10; +-----+--------------------------+ | id | tagsid | +-----+--------------------------+ | 4 | 2863,4351,4353 | | 10 | 2689,4349,2863 | | 78 | 2863,2197,4327 | | 245 | 3395,2863 | | 85 | 2863,2497,3869,4315 | | 108 | 2193,4301,2863,4303 | | 121 | 4277,2863,4279,3311,3215 | | 122 | 4277,4279,2863,4189,3109 | | 137 | 3361,3811,2829,3255,2863 | | 149 | 2289,2197,2863,2519,4199 | +-----+--------------------------+ 10 rows in set (0.00 sec)
初步查看并没有什么区别,紧紧在使用方法有所不同,由于查询量比较小,也未做压力测试,查询效率也就不曾而知了,但对于用法上,可根据自己的需求,选择性使用。对于大数据的查询,建议还是数据层上面搭建一个缓冲层,避免对数据库的实时查询等操作,比如索引,缓存,等等措施,毕竟全文查询对mysql压力实在是太大,以上均为本人拙见。