mysql模糊查询函数

时间:2021-07-26 09:20:00
这两天在做关键字搜索,查了不少资料,得知如果要查询的关键字在开头,例如:LIKE %title%,那么效率会很多,在网上看到有人用这种办法来解决关键字在开头的问题。
一张表大概40万左右的数据,用like模糊查询title字段,很慢,title字段已经建立了索引,mysql 对 someTitle% 这样的模糊查询在有索引的前提下是很快的。
所以下面这两台sql语句差别就很大了 
$sql1 = "...... title like someTitle%" (话费0.001秒)
$sql2 = "...... title like %someTitle%" (话费0.8秒)
这两句的效率相差了800倍,这很可观啊。
所以我有个想法:在不用分词的方法的前提下,把存储的title字段,加一个特别的前缀,比如"im_prefix",比如一条记录的title="我是标题党",那么存储的时候就存储为"im_prefix我是标题党"。
这样一来,我们要模糊查找"标题党"这个关键词的时候,就把sql写成这样:

$sql1 = "...... title like im_prefix%标题党%" (花费0.001秒),前台显示数据的时候,自然把取到的title过滤掉"im_prefix"这个前缀了。

总的来说,就是在存储的时候,每一次都在 要存储的内容加上一个固定的字段,以此来让需要查询的内容不在开头,这样就可以 LIKE title%的形式代替LIKE %title%,从而提高效率。
本人强迫症患者,自然是不想用这种办法,于是就改用了其他方法,locate(locate 的別名 position)或者substr。 LOCATE(substr,str); 返回子串 substr 在字符串 str 中第一次出现的位置。如果子串 substr 在 str 中不存在,返回值为 0
SELECT LOCATE('bar', 'foobarbar');      或者SELECT POSITION('bar' IN 'foobarbar'); 返回4
LOCATE(substr,str,pos);
返回子串 substr 在字符串 str 中的第 pos 位置后第一次出现的位置。如果 substr 不在 str 中返回 0 :
SELECT LOCATE('bar', ‘foobarbar',5);
返回7
然后实现模糊查询:select * from tablename where LOCATE('bar', ‘foobarbar',5)>0 INSTR(str,substr);
返回字符串str串中substr子串第一个出现的位置。这与LOCATE()的双参数形式是一样的,不同的是参数的顺序是相反的
SELECT INSTR('foobarbar', 'bar');
返回4
locate、position 和 instr 的差別只是参数的位置不同,同时locate 多一个请始位置的参数外,两者是一样的。速度上这三个比用 like 稍快了一點。 而find_IN_SET则是当字需要作为参数传递时,为了避免因为类型的原因 而查询结果错误的问题(SELECT POSITION('bar' IN 'foobarbar') keyword 为int类型时,则查询结果总是为一条) 应使用find_IN_SET代替。find_int_set(列名,$a) ; 当表中无数据或者列为null时,LOCATE会成立 find_IN_SET 比较严格 如果没有数据 则不成立
(其实一开始是有小伙伴告诉我让我用 charindex ,无奈的是mysql并没有这个。) 2017年3月3日