V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
salamanderMH
V2EX  ›  问与答

MongoDB 复合索引的一个问题?

  •  
  •   salamanderMH · 2019-08-12 16:12:01 +08:00 · 1069 次点击
    这是一个创建于 1948 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    我给表建了一个 {nickname: 1, follower_count: -1} 的索引,follower_count 是粉丝数,然后想左前缀查询用户的时候按粉丝数倒序出结果,这是语句

    collection.find( nickname: { '$regex': /^${name}.*/ }).sort({follower_count: -1}).limit(20)
    

    看执行计划,用的索引是follower_count的单列索引,而没用 {nickname: 1, follower_count: -1} 这个复合的索引,很奇怪?

    6 条回复    2019-08-14 15:13:11 +08:00
    snBDX1b0jJM4ogKd
        1
    snBDX1b0jJM4ogKd  
       2019-08-13 00:27:06 +08:00 via Android
    因为你查询的时候,nickname 是正则,没法走索引
    salamanderMH
        2
    salamanderMH  
    OP
       2019-08-13 09:42:20 +08:00
    @cs010 但也是最前缀匹配的
    snBDX1b0jJM4ogKd
        3
    snBDX1b0jJM4ogKd  
       2019-08-13 10:15:37 +08:00 via Android
    @salamanderMH 用正则应该走全表扫描,怎么还会前缀匹配。你把正则换了,肯定就走索引了啊
    salamanderMH
        4
    salamanderMH  
    OP
       2019-08-13 10:40:28 +08:00
    @cs010 MySQL 中用 LIKE 'name%'是可以用到索引的。
    snBDX1b0jJM4ogKd
        5
    snBDX1b0jJM4ogKd  
       2019-08-13 14:18:34 +08:00
    @salamanderMH 抱歉,我先前回答并不准确,你不妨贴一下你的执行计划和 mongo 版本
    salamanderMH
        6
    salamanderMH  
    OP
       2019-08-14 15:13:11 +08:00
    @cs010 我把语句改成了
    collection.find( nickname: { '$regex': /^${name}.*/ }).sort({nickname:1, follower_count: -1}).limit(20)
    就可以命中索引了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5086 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:32 · PVG 15:32 · LAX 23:32 · JFK 02:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.