日期:2014-05-17  浏览次数:20375 次

关于mysql set字段类型的模糊查询问题
有个40万条的测试数据表
flag  set('r', 'l', 'c', 'p') 

SELECT a. * , b.typedir
FROM mzrui_archives a
LEFT JOIN mzrui_kind b ON a.kid = b.uid
WHERE a.flag LIKE '%p%'
AND a.kid
IN ( 3, 17, 18 )
ORDER BY a.uid
LIMIT 0 , 15

这个语句查询需要2.5秒的时间,把like去掉后查询相当快,不知道怎么优化,求教。

uid是主键
key kid(kid,flag) 索引

------解决方案--------------------
既然是set,为何要like查询?  find_in_set('p',a.flag)
------解决方案--------------------
引用:
Quote: 引用:

既然是set,为何要like查询?  find_in_set('p',a.flag)


find_in_set 的效率也是一样,我测试了,关键是find_in_set不能('c,p',a.flag)多条件,这样我查不出记录来


你可以
find_in_set('p',a.flag) and find_in_set('c',a.flag)

------解决方案--------------------
如果你仅仅4个标识('r', 'l', 'c', 'p') ,不如用 1 2 4 8 作为标识位,用例如 1
------解决方案--------------------
2 = 3 的方式来标识flag,查询的时候可以 where flag & 2 的方式,应该会快不少
------解决方案--------------------
对于 set 类型字段 find_in_set 用的就是位运算
不过 like '%l%' 这样肯定是不可取的,如果是 like '%l,r%' 或 like '%l,p%' 不就什么都找不到了吗?
当然,无论是 like 还是 find_in_set 都是要遍历整个表的,不然就不知道哪条记录能匹配的上
set 类型是按长整形存储的,加上索引可能会快些