mysql 的 like %字段% 如何优化

2016-11-04 11:10:23 +08:00
 lianxiaoyi

mysql 在 like %字段%情况下没法使用索引,现有 sql

SELECT * FROM 表 WHERE (text1=100) AND text2 LIKE "%ssss%" order by id desc LIMIT 20

在 100 多万条数据下挂了

后来改了一版

SELECT * FROM WHERE (text1=113) AND INSTR(text1, "ssss") order by id desc LIMIT 20

符合 text1 值比较少的情况下速度还行吧,但是多了之后也挂了

text1 和 text2 有联合索引

10113 次点击
所在节点    MySQL
49 条回复
lianxiaoyi
2016-11-04 11:15:53 +08:00
数据库引擎 innerDB ,不允许改动
shimanooo
2016-11-04 11:16:47 +08:00
holyghost
2016-11-04 11:17:34 +08:00
100w 再不上 es 说不过去了吧
qiayue
2016-11-04 11:18:07 +08:00
如果数据实在太多,对需要 like 的字段做一个倒排索引,那就速度飞起了
lianxiaoyi
2016-11-04 11:23:44 +08:00
@holyghost es ???不懂。。。。。

@qiayue 我去百度查一下这个概念....跪谢大神
lianxiaoyi
2016-11-04 11:24:02 +08:00
@shimanooo 感谢。。。我去看看。。。
zwh8800
2016-11-04 11:37:58 +08:00
把需要搜索的数据同步一份到 elasticsearch 上,然后重构整个搜索服务,所有用到 like 的地方都换成调用 elasticsearch 。

一般企业里数据量过大之后,搜索都是这么做的。
skyleft
2016-11-04 11:42:02 +08:00
5.6 以上 innodb 也支持 fulltext
lianxiaoyi
2016-11-04 11:45:22 +08:00
@zwh8800 我曾想过 sphinx 。。。然后查询出一个 id ,,然后我再根据 id 去 in 查询。。。。但是工作量有点大。。毕竟程序员都很懒。。。啊哈哈。。。。实在不行就改吧 。。。。。。
lianxiaoyi
2016-11-04 11:46:36 +08:00
@skyleft 我刚实验了一下。。。 varchar 字段没法使用 fulltext 索引哇。。。。。
mooncakejs
2016-11-04 12:03:44 +08:00
100w 用 es 杀牛吗? fulltext 就好了
lianxiaoyi
2016-11-04 12:19:39 +08:00
@mooncakejs 大神。。。。。我去试试。。。。。
Felldeadbird
2016-11-04 12:27:24 +08:00
升级到最新版 MYSQL , innodb 支持 fulltext 。好像 5.7 有支持中文全文搜索的方法。当然,数据量大了,还是用第三方的插件去做全文搜索吧。
ebony0319
2016-11-04 12:36:53 +08:00
我有大量的数据都是跟你一样的。我的经验是这样的。查两次。
第一次在用户输入的时候去查数据库,然后自动补全。就像搜索你在淘宝搜索的时候给你补全。
第二次在查的话就可以用=了。
这样查的好处就是第一次查询其实速度是非常快的。如果第二个表联结很多表。可以使用到索引。
wujunze
2016-11-04 13:08:58 +08:00
elasticsearch +1
chaegumi
2016-11-04 14:05:35 +08:00
@mooncakejs

@lianxiaoyi

果断 elasticsearch
mooncakejs
2016-11-04 14:08:35 +08:00
@chaegumi 100w fulltext search 照样可以毫秒级搜索,免去了 es 同步 mysql 的问题。
lianxiaoyi
2016-11-04 14:17:44 +08:00
@mooncakejs 我正在实验。。。啊哈哈
enenaaa
2016-11-04 14:36:44 +08:00
刚试过 5.7 的 innodb 虽然支持 fulltext , 但 3 个字以下的还是匹配不了,改了 ft_min_word_len 也不行, MyISAM 可以。
由于中文分词问题,全文索引貌似也不太适合直接替换 like 。 可以考虑第三方, 或者分阶段分表查询
lianxiaoyi
2016-11-04 14:39:21 +08:00
@enenaaa
@mooncakejs
大神 为啥
SELECT * FROM `表` WHERE MATCH (字段 1) against ('2b4a640ec7617c652824' in boolean mode) ;

查询不出数据啊??用 like 查是有 3 条数据的......

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/317970

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX