V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
enjoychen0318
V2EX  ›  程序员

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

  •  
  •   enjoychen0318 · 212 天前 · 2623 次点击
    这是一个创建于 212 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一张 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  
       212 天前
    mysql 有个全文检索索引。你可以调研下,能不能支持百万级数据。估摸着可以用。
    qaweqa
        2
    qaweqa  
       212 天前
    试试用 instr()
    enjoychen0318
        3
    enjoychen0318  
    OP
       212 天前   ❤️ 1
    @damai0419 如果用全文索引我感觉 elasticsearch 会好很多,但是全文索引的分词会导致有些搜索不准确吧
    enjoychen0318
        4
    enjoychen0318  
    OP
       212 天前
    @qaweqa 试了下。。百万行的数据查询好像和 like 差不多
    cha0sCat
        5
    cha0sCat  
       212 天前
    pg 有一个 pg-trgm 索引的原理和你说的差不多
    基本是把关键词 'abcd' 拆分成 ' a' ' ab' 'abc' 'bcd' 'cd ' 这样查询
    outdoorlife
        6
    outdoorlife  
       212 天前
    @enjoychen0318

    我同意你的用 ELK 来做

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

    包括未来你要做数据 ETL 你也不可能主库抽,抽一次主库死了,只从从库抽。
    zhoudaiyu
        7
    zhoudaiyu  
       212 天前 via iPhone
    不知道 Loki 能不能 cover 这种场景
    tinybaby365
        8
    tinybaby365  
       212 天前
    优先用 elasticsearch ,想省钱就用 postgres 。
    dusu
        9
    dusu  
       212 天前 via iPhone
    manticoresearch 中小企业全文搜索伴侣
    WhereverYouGo
        10
    WhereverYouGo  
       211 天前
    ES ,字段用 ngram 分词器,匹配时用 match_phrase 语句。
    ferstar
        11
    ferstar  
       211 天前 via Android
    才百万,pg gin 索引了解下
    ospider
        12
    ospider  
       211 天前
    才百万……命令行用 fzf 都行
    SmiteChow
        13
    SmiteChow  
       210 天前
    瞧不起 mysql 的索引吗?如果字段没有超过 255 字符,mysql 模糊查找没有任何问题。

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

    当然, 用上面说的各种方案肯定是更加靠谱的.
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1166 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:29 · PVG 04:29 · LAX 13:29 · JFK 16:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.