百万级数据的模糊查询,求方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
enjoychen0318
V2EX    程序员

百万级数据的模糊查询,求方案

  •  
  •   enjoychen0318 2022-01-08 19:07:29 +08:00 4354 次点击
    这是一个创建于 1447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一张 mysql 的 data 表有 300 个 varchar 字段:value1 到 value300 ,想要支持模糊查询,
    想到的办法是建立一张索引表,

    id, data_id, data 表的 id number, 数据在 data 表中的位置 value, 数据的值 

    然后加上索引 data_id,number,value ,但是这样只能加速前缀匹配

    现在有个想法,比如value 等于"abcdefghi" 就往 index 表插入以下数据,

    abcdefghi, bcdefghi, cdefghi, defghi, ... 

    这样就能支持 "%ced%"的快速查询了, 但是数据量会很大,data 表数据百万的话,可能 index 就几十亿了,这种方案可行么?

    大家有没更好的方案?比如说 index 表 用 elasticsearch?

    15 条回复    2022-01-10 11:04:26 +08:00
    damai0419
        1
    damai0419  
       2022-01-08 19:17:26 +08:00
    mysql 有个全文检索索引。你可以调研下,能不能支持百万级数据。估摸着可以用。
    qaweqa
        2
    qaweqa  
       2022-01-08 19:19:53 +08:00
    试试用 instr()
    enjoychen0318
        3
    enjoychen0318  
    OP
       2022-01-08 19:36:51 +08:00   1
    @damai0419 如果用全文索引我感觉 elasticsearch 会好很多,但是全文索引的分词会导致有些搜索不准确吧
    enjoychen0318
        4
    enjoychen0318  
    OP
       2022-01-08 19:37:29 +08:00
    @qaweqa 试了下。。百万行的数据查询好像和 like 差不多
    cha0sCat
        5
    cha0sCat  
       2022-01-08 20:08:39 +08:00
    pg 有一个 pg-trgm 索引的原理和你说的差不多
    基本是把关键词 'abcd' 拆分成 ' a' ' ab' 'abc' 'bcd' 'cd ' 这样查询
    outdoorlife
        6
    outdoorlife  
       2022-01-08 20:15:12 +08:00
    @enjoychen0318

    我同意你的用 ELK 来做

    另外可以考虑直接个只读库,只干这种非实时操作的。这是我们在没有 HADOOP 没有 ELK 的 2015 年前最常见的也是最有效的办法。

    包括未来你要做数据 ETL 你也不可能主库抽,抽一次主库死了,只从从库抽。
    zhoudaiyu
        7
    zhoudaiyu  
    PRO
       2022-01-08 20:44:18 +08:00 via iPhone
    不知道 Loki 能不能 cover 这种场景
    tinybaby365
        8
    tinybaby365  
       2022-01-08 21:20:37 +08:00
    优先用 elasticsearch ,想省钱就用 postgres 。
    dusu
        9
    dusu  
       2022-01-09 02:49:48 +08:00 via iPhone
    manticoresearch 中小企业全文搜索伴侣
    Masonnn
        10
    Masonnn  
       2022-01-09 13:11:23 +08:00
    ES ,字段用 ngram 分词器,匹配时用 match_phrase 语句。
    ferstar
        11
    ferstar  
       2022-01-09 15:18:10 +08:00 via Android
    才百万,pg gin 索引了解下
    4BVL25L90W260T9U
        12
    4BVL25L90W260T9U  
       2022-01-09 19:02:23 +08:00
    才百万……命令行用 fzf 都行
    SmiteChow
        13
    SmiteChow  
       2022-01-10 09:25:34 +08:00
    瞧不起 mysql 的索引吗?如果字段没有超过 255 字符,mysql 模糊查找没有任何问题。

    超过了就不合适了,看你的描述也不需要分词那就上 mongodb 。
    py88pQ2hZ7PJw0v4
        14
    py88pQ2hZ7PJw0v4  
       2022-01-10 09:51:06 +08:00
    MoYi123
        15
    MoYi123  
       2022-01-10 11:04:26 +08:00
    你的想法叫做"后缀数组" https://oi-wiki.org/string/sa/
    不过不需要把字符串真的完全切开,只需要存从 0,1,2,3... 开始的字符串的 rank 值即可, 查的时候用二分查找,
    生成的时间复杂度是 O(n),查找是 O(m * log(n)), (n 是整个字符串的长度,m 是查询串的长度)
    如果你很想在工作的代码里整活的话也不是不能用.

    当然, 用上面说的各种方案肯定是更加靠谱的.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2640 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 15:23 PVG 23:23 LAX 07:23 JFK 10:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86