ads-mysql版 sql中子查询和等号执行效率差异巨大

一个大sql,其中一个条件
处理方式1:
不使用子查询比如
code=‘123’执行 70ms
处理方式2:
带子查询条件,比如
code in(select xxx from table where xxx)
其中子查询sql
select xxx from table where xxx 单独执行100ms
结果也是就一个值‘123’场景
这种方式执行时间18s;

疑问:业务场景中无法避免使用方式2 只能使用动态数据去获取code范围,用户量上来后同时调用此接口后数据库就撑不住了,问下大神怎么去调整一下这个方式让sql跑的更快呢

展开
收起
1867016090850207 2024-09-12 23:19:06 138 发布于北京 分享
分享
版权
举报
1 条回答
写回答
取消 提交回答
  • 针对您提到的SQL执行效率问题,特别是在必须使用子查询来动态获取code范围的情况下,以下是一些基于参考资料的专业建议来优化您的查询性能:

    1. 优化子查询

    使用JOIN替换IN子查询

    根据参考资料,当子查询返回结果较多时,可以考虑使用JOIN来替代IN子查询。这不仅能够避免因返回结果超过限制而导致的错误,还能在某些情况下提高查询效率。示例如下:

    SELECT a.*
    FROM table_a a
    JOIN (
        SELECT DISTINCT col1
        FROM table_b b
        WHERE xxx
    ) c ON a.code = c.col1;
    

    注意:如果业务上保证子查询结果中col1列值无重复,可移除DISTINCT关键字以进一步提升性能。

    2. 确保索引有效

    • 确认涉及到的列是否有合适的索引。特别是对于table_b中用于筛选xxx条件的列以及最终JOIN操作中使用的列,应确保它们被索引覆盖,以减少扫描成本。

    3. 调整JOIN策略

    • 在JOIN操作中,合理安排表的连接顺序和条件放置位置。尽量将主表的分区限制条件放在WHERE子句中,并将从表的分区限制条件放在ON条件或子查询中,以减少不必要的数据扫描。

    4. 优化器Join Order算法

    • 如果JOIN关系复杂或涉及多表,尝试调整优化器的Join Order算法。虽然默认的exhaustive2算法通常能找到最优解,但在表数量较大时优化耗时较长。在某些场景下,可以尝试使用greedy算法减少优化器耗时,尽管这可能不会产生最优计划。

    5. 减少Motion算子

    • 确保数据分布策略(如Distribution Key)与JOIN条件相匹配,以减少数据重分布的需求。通过调整表的分布键,使得JOIN操作能够在数据已正确分布的Shard间直接进行,避免不必要的数据移动和网络开销。

    6. 避免不必要的函数转换和类型转换

    • 确保查询中不包含导致索引失效的操作,如函数转换、类型转换或非开头的LIKE操作。

    7. HQE引擎优化

    • 检查是否所有部分都能在高性能的HQE引擎中执行。避免使用可能导致查询被发送到PQE执行的操作,如NOT IN,并考虑将其改写为NOT EXISTS形式。

    综上所述,通过上述策略的综合应用,可以在很大程度上优化包含子查询的大SQL执行效率,减轻数据库压力,尤其是在用户量增加的场景下。务必根据实际的表结构、数据分布和查询需求,灵活选择和调整优化措施。

    2024-09-12 23:54:00 举报
    赞同 298 1

    评论

    全部评论 (1)

    登录后可评论
    头像
    ads的索引应该是全表索引,不需要再建立索引了;今天试了下把子查询作为一个小临时表去查询,效果就上来了 达到70ms左右 with b as(select xxx from c where c.01=xxx) select from a join b on(xxx) 这种没问题,但是发现c。01 换个条件c.02的时候 查询就又和之前一样慢了18s左右,找了半天也没发现问题
    2024-09-13 23:22:54
    赞同1
问答分类:

阿里云自主研发的云原生数据仓库,具有高并发读写、低峰谷读写、弹性扩展、安全可靠等特性,可支持PB级别数据存储,可广泛应用于BI、机器学习、实时分析、数据挖掘等场景。包含AnalyticDB MySQL版、AnalyticDB PostgreSQL 版。

热门讨论

热门文章

还有其他疑问?
咨询AI助理