开发者社区 > 云原生 > 中间件 > 正文

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 76 0
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
    赞同 123 展开评论 打赏
问答分类:
问答地址:

为企业提供高效、稳定、易扩展的中间件产品。

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载