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

mysql,关于模糊查询百分号放在前面,索引的使用问题,求教!

  •  
  •   Gaussen · 2018-12-13 22:09:19 +08:00 · 6204 次点击
    这是一个创建于 2172 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前有了解到,即使查询条件字段有设置索引,在使用模糊查询的时候,将百分号放在前面,也是无法触发索引的。

    select region from user where name like '%908';

    那如果说,我希望能够这么进行模糊查询,同时还可以使用 name 的索引,可以实现吗?

    22 条回复    2018-12-15 11:23:51 +08:00
    jybox
        1
    jybox  
       2018-12-13 22:13:28 +08:00   ❤️ 1
    不能实现。
    Gaussen
        2
    Gaussen  
    OP
       2018-12-13 22:14:11 +08:00
    @jybox 好的,谢谢解答。
    jybox
        3
    jybox  
       2018-12-13 22:15:07 +08:00   ❤️ 4
    你可以把 name 字段倒着存一份,比如存个 rname = nessuaG,然后想查 %ssen 的话就倒着查 rname like ness% 就可以用 rname 上的索引了。
    Gaussen
        4
    Gaussen  
    OP
       2018-12-13 22:18:00 +08:00
    @jybox 好主意!
    hdonghong
        5
    hdonghong  
       2018-12-13 22:51:13 +08:00
    考虑覆盖索引?
    Gaussen
        6
    Gaussen  
    OP
       2018-12-13 23:11:26 +08:00
    @hdonghong 没有使用过,数据库我懂的比较少。
    nimabibi
        7
    nimabibi  
       2018-12-13 23:52:30 +08:00 via iPhone
    请了解 reverse 函数用法
    jadec0der
        8
    jadec0der  
       2018-12-14 00:57:45 +08:00
    @nimabibi 你是认真的么。lz 要索引,用 reverse 是想每次查询的时候都计算然后比较么?那还是扫全表啊
    artist
        9
    artist  
       2018-12-14 10:03:23 +08:00
    @jadec0der explain 看下呢。
    pain400
        10
    pain400  
       2018-12-14 10:24:36 +08:00
    @hdonghong 你得先用上索引。。。
    jadec0der
        11
    jadec0der  
       2018-12-14 11:54:35 +08:00
    @artist 你们就不能多说两句么? explain 什么?? reverse 函数的什么用法??

    我能想到三个 reverse 的用法:

    1. where reverse(name) like '908%'; 这种肯定是扫全表,比原来还慢

    2. 用 generated column 建索引,跟 3L 的方案本质上是一样的,能少写点代码,但是需要高版本的 MySQL

    3. 直接用 reverse(name) 建索引,据我所知 MySQL 不支持

    所以我认为 reverse 解决不了这个问题,但是我依然想聆听一下 7L 的高见,如果 7L 没有高见,我就要 block 你们这些三词怪了
    jadec0der
        12
    jadec0der  
       2018-12-14 11:55:54 +08:00
    @jadec0der typo like '809%';
    dreamans
        13
    dreamans  
       2018-12-14 12:05:47 +08:00
    生产环境的话,还是借助 es 之类的检索服务吧
    Exceptions
        14
    Exceptions  
       2018-12-14 13:21:03 +08:00
    @jadec0der 哈哈 ,见多不怪
    nimabibi
        15
    nimabibi  
       2018-12-14 13:23:50 +08:00
    @jadec0der create index reverse(field) ,查询 where reverse(field) like (reverse('%value')),我要是你,就先拿着这个 reverse 放到搜索引擎先去查下有没有,而不是自以为是的,在这里无脑喷,什么年代了,搜索不会用了,mysql reverse like 索引优化,不会搜索了?
    Donne
        16
    Donne  
       2018-12-14 14:07:50 +08:00
    @nimabibi 函数索引是 oracle 吧,MySQL 没找见这种操作。
    atpking
        17
    atpking  
       2018-12-14 15:06:31 +08:00
    可以取巧的

    就是在做表的时候 直接建立一列 reverse_named_column

    之后在每次存储和修改的时候 及时的算一份, 存在 reverse_named_column 上 (Rails 里是 before_save )

    之后就可以按照之前用户说的 反查了

    当然这种是取巧的方式,


    上 elk 可以本质上解决问题
    jadec0der
        18
    jadec0der  
       2018-12-14 15:14:51 +08:00
    @nimabibi 请允许我为我的「自以为是」、「无脑喷」和「不会搜索」道歉,我确实没有搜索到这个用法,请先生教我。

    假设我有一个表:

    CREATE TABLE `docs` (
    `id` int(6) unsigned NOT NULL,
    `content` varchar(200) NOT NULL,
    PRIMARY KEY (`id`)
    ) DEFAULT CHARSET=utf8;

    请问 create index reverse(field) 的语句具体怎么写呢?

    我试了 CREATE INDEX rev_content ON docs(REVERSE(content)); 这样不行呀
    Lwf1995
        19
    Lwf1995  
       2018-12-14 16:04:24 +08:00
    你可以试试那啥 locate (‘ AAA ’ , table.field) > 0
    nimabibi
        20
    nimabibi  
       2018-12-14 22:14:44 +08:00 via Android
    jadec0der
        21
    jadec0der  
       2018-12-15 09:42:38 +08:00 via Android
    @nimabibi 哪个版本的 MySQL 支持这种用法? cerate index 索引名称 on 表名(reverse(列名));
    megatron7
        22
    megatron7  
       2018-12-15 11:23:51 +08:00
    right() substr() instr() 试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   925 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:25 · PVG 06:25 · LAX 14:25 · JFK 17:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.