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

请教一个 sql 优化问题

  •  
  •   EggplantLover · 2023-06-27 10:13:04 +08:00 · 1855 次点击
    这是一个创建于 365 天前的主题,其中的信息可能已经有所发展或是发生改变。
    摘了一段导致执行慢的条件,这种应该怎么优化

    task.assignee_id_ = '123'
    AND
    (
    (
    task.STATUS_ = 'LOCK'
    and
    (
    linkd.IDENTITY_ = '123'
    or linkd.TYPE_ != 'user'
    )
    )
    or
    task.STATUS_ != 'LOCK'
    )

    列 task.assignee_id_、linkd.IDENTITY_已经加了索引
    19 条回复    2023-06-27 16:17:39 +08:00
    EggplantLover
        1
    EggplantLover  
    OP
       2023-06-27 10:14:25 +08:00
    去掉这段条件执行时间可以减少两秒,查询的表数据量都不大,几万行左右
    Stevenv
        2
    Stevenv  
       2023-06-27 10:24:17 +08:00
    你先 explain 执行 SQL, 看看索引的使用情况
    Alias4ck
        3
    Alias4ck  
       2023-06-27 10:36:10 +08:00
    什么数据库,几万行的查询, 为啥可以这么慢😧
    MartinDai
        4
    MartinDai  
       2023-06-27 10:40:33 +08:00
    task.assignee_id 和 linkd.IDENTITY 看起来都是数字类型的 不要使用字符串做查询,改成数字
    Hieast
        5
    Hieast  
       2023-06-27 10:41:31 +08:00
    linkd 和 task 不是一张表吧,多了 join ?
    MartinDai
        6
    MartinDai  
       2023-06-27 10:41:42 +08:00
    还有就是如果数据量这么小,完全可以在内存里做过滤
    AND((task.STATUS_ = 'LOCK' and (linkd.IDENTITY_ = '123' or linkd.TYPE_ != 'user')) or task.STATUS_ != 'LOCK')
    这后面的条件都可以去掉
    wanniwa
        7
    wanniwa  
       2023-06-27 10:44:14 +08:00
    把 or 拆成两个 sql 在数据里里试试两个哪个执行的慢,如果都快的话,看要不要就拆成两句直接 union 。如果分析出来哪个单句慢的话再针对单句继续优化
    第一句
    task.assignee_id_ = '123'
    AND
    (
    task.STATUS_ = 'LOCK'
    and
    (
    linkd.IDENTITY_ = '123'
    or linkd.TYPE_ != 'user'
    )
    第二句
    task.assignee_id_ = '123'
    AND task.STATUS_ != 'LOCK'
    DissDoge
        8
    DissDoge  
       2023-06-27 10:45:55 +08:00
    可以考虑以下几点:

    使用合适的索引:确保 task.assignee_id_和 linkd.IDENTITY_的索引是正确创建的。你提到已经添加了索引,但需要确保索引的创建方式正确,并且统计信息是最新的。可以使用数据库的索引优化工具或者执行计划分析来确认索引是否被有效使用。

    优化逻辑表达式:该条件涉及多个逻辑运算符( AND 、OR ),可以尝试重新组织条件表达式,优化逻辑判断的顺序。例如,可以将常见的判断条件放在前面,以便更早地过滤掉不符合条件的记录。

    考虑联合索引:如果 task.assignee_id_和 task.STATUS_、linkd.IDENTITY_和 linkd.TYPE_之间有相关性,可以考虑创建联合索引。联合索引可以更好地支持多个列的组合条件查询,提高查询效率。

    数据库性能调优:除了索引优化外,还可以考虑其他数据库性能调优技术。例如,分析和优化查询计划、调整数据库配置参数、增加硬件资源等。

    数据库版本升级:如果你使用的是较旧版本的数据库,可以考虑升级到最新版本,以获得更好的性能优化和查询优化器。

    需要注意的是,优化查询的方法因数据库类型和版本而异。建议在具体情况下,结合数据库性能监控和优化工具,以及参考相关数据库的优化文档,针对具体的数据库系统进行优化调整。
    8355
        9
    8355  
       2023-06-27 10:47:50 +08:00   ❤️ 1
    简单做法 拆分 sql
    你这样分行真的看着有点心态爆炸
    原代码
    task.assignee_id_ = '123'
    AND
    (
    (task.STATUS_ = 'LOCK' and (linkd.IDENTITY_ = '123' or linkd.TYPE_ != 'user'))
    or task.STATUS_ != 'LOCK'
    )

    改进后
    task.assignee_id_ = '123' and task.STATUS_ != 'LOCK'
    task.assignee_id_ = '123' and task.STATUS_ = 'LOCK' and linkd.IDENTITY_ = '123'
    task.assignee_id_ = '123' and task.STATUS_ = 'LOCK' and linkd.TYPE_ != 'user'
    3 组数据按照你原本排序需求代码写下排序就行

    如果 task.assignee_id_ = '123'查的结果并不多实际应该通过遍历过滤更快
    数据库基本原则简单查询多次比复杂查询一次要快
    ooee2016
        10
    ooee2016  
       2023-06-27 10:53:30 +08:00
    新加个字段表示这段逻辑的状态
    eightyfive
        11
    eightyfive  
       364 天前
    拆分 sql ,explain 一下,看看是否有索引,以及确认 sql 字段走索引的前后顺序
    kkwa56188
        12
    kkwa56188  
       364 天前
    试试把 linkd 相关的条件, 改用 exists 重写子句, 这样 就不用在 主 查询 里 join 一次
    0x1111
        13
    0x1111  
       364 天前
    show create table
    explain
    select count(distinct(assignee_id_))

    没有表结构和 explain 不好具体分析,字段加索引不一定最有,还要看下列的分散度
    EggplantLover
        14
    EggplantLover  
    OP
       364 天前
    @8355 #9 这样改了时间上没有变化,可能解析器最终都会改成一样的
    akira
        15
    akira  
       364 天前
    就 2 个几万行的表 jion 的话,应该是随便 zuo 的,数据库配置那边也看一眼呢。
    EggplantLover
        16
    EggplantLover  
    OP
       364 天前
    @akira #15 一共十个表 join ,我把比较慢的条件摘了出来
    8355
        17
    8355  
       364 天前
    @EggplantLover #14 没有变化就是你索引的问题了,or 是不走索引的, 如果你原本就没有索引的话。。。。。。。。。
    tairan2006
        18
    tairan2006  
       364 天前
    10 个表 join…与其优化 sql 不如搞个物化视图或者做个宽表……
    EggplantLover
        19
    EggplantLover  
    OP
       364 天前
    @Alias4ck #3 达梦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5365 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 03:02 · PVG 11:02 · LAX 20:02 · JFK 23:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.