永远用小的结果集驱动大的结果集

永远用小的结果集驱动大的结果集

转载自:公司内  数据工程师:

 永远用小的结果集驱动大的结果集

很多人喜欢在优化 SQL 的时候使用小表驱动大表,个人认为这不太严谨。为什么?因为大表经过 WHERE 条件过滤之后返回的结果集并不一定就比小表所返回的大,也许更小。在这种情况下如果仍然采用小表驱动大表,就会得到相反的性能效果。 

其实这也非常容易理解,在MySQL中,只有 Nested Loop 一种 Join 方式,也就是说MySQL的 Join 都是通过嵌套循环来实现的。驱动结果集越大,所需要循环就越多,那么被驱动表的访问次数自然也就越多,而每次访问被驱动表,即使需要的逻辑 IO 很少,循环次数多了,总量也不可能小,而且每次循环都不能避免消耗CPU,所以 CPU 运算量也会跟着增加。如果仅仅以表的大小来作为驱动表的判断依据,假若小表过滤后所剩下的结果集比大表多很多,结果就会在嵌套循环中带来更多的循环次数,反之,所需要的循环次数就会更少,总体 IO 量和 CPU 运算量也会更少。在非 Nested Loop  的 Join  算法中,如 Oracle  中的 Hash  Join,小结果集驱动大的结果集同样是最优的选择。 

所以,在优化 Join Query 的时候,最基本的原则就是“小结果集驱动大结果集”,通过这个原则来减少嵌套循环中的循环次数,以减少 IO总量及CPU运算的次数。 

SELECT
  pproductpr0_.p_product_prop_id AS col_0_0_,
  pproductpr0_.p_product_prop_code AS col_1_0_,
  pproductpr0_.p_product_prop_name AS col_2_0_,
  CASE WHEN pproductpr0_.p_product_prop_val IS NULL THEN ” ELSE pproductpr0_.p_product_prop_val END AS col_3_0_,
  pproductpr0_.p_product_prop_order AS col_4_0_,
  (SELECT
      bdic4_.b_dic_code
    FROM b_dic bdic4_
    WHERE bdic4_.b_dic_id = pproductpr0_.p_product_prop_must) AS col_5_0_,
  pproductpr0_.p_product_prop_status AS col_6_0_,
  (SELECT
      bdic5_.b_dic_code
    FROM b_dic bdic5_
    WHERE bdic5_.b_dic_id = pproductpr0_.p_product_prop_display) AS col_7_0_,
  pproductpr0_.p_product_prop_source AS col_8_0_,
  pproductpr0_.p_product_prop_int_code AS col_9_0_,
  pproduct3_.p_product_id AS col_10_0_,
  pproductpr0_.p_product_prop_default_value AS col_11_0_,
  (SELECT
      bdic6_.b_dic_code
    FROM b_dic bdic6_
    WHERE bdic6_.b_dic_id = pproductpr0_.p_product_prop_available) AS col_12_0_,
  (SELECT
      bdic7_.b_dic_code
    FROM b_dic bdic7_
    WHERE bdic7_.b_dic_id = pproductpr0_.p_product_prop_width) AS col_13_0_,
  (SELECT
      bdic8_.b_dic_code
    FROM b_dic bdic8_
    WHERE bdic8_.b_dic_id = pproductpr0_.p_product_prop_valid_type) AS col_14_0_,
  pproductty2_.p_ptp_classify_id AS col_15_0_,
  pproductty1_.p_ptype_prop_id AS col_16_0_,
  (SELECT
      bdic9_.b_dic_code
    FROM b_dic bdic9_
    WHERE bdic9_.b_dic_id = pproductpr0_.p_product_prop_source_type) AS col_17_0_,
  pproductpr0_.p_product_display_format AS col_18_0_,
  pproductpr0_.p_product_value_field AS col_19_0_,
  pproductpr0_.p_product_text_field AS col_20_0_,
  pproductpr0_.p_product_min_length AS col_21_0_,
  pproductpr0_.p_product_max_length AS col_22_0_,
  pproductpr0_.p_product_event_source AS col_23_0_,
  pproductpr0_.p_product_prop_prop_name AS col_24_0_,
  pproductpr0_.p_product_prop_create_on AS col_25_0_,
  pproductpr0_.p_product_prop_create_by AS col_26_0_,
  pproductpr0_.p_product_prop_update_on AS col_27_0_,
  pproductpr0_.p_product_prop_update_by AS col_28_0_
FROM p_product_prop pproductpr0_
  LEFT OUTER JOIN p_product_type_prop pproductty1_
    ON pproductpr0_.p_ptype_prop_id = pproductty1_.p_ptype_prop_id
  LEFT OUTER JOIN p_product_type_prop_classify pproductty2_
    ON pproductty1_.p_ptp_classify_id = pproductty2_.p_ptp_classify_id
  LEFT OUTER JOIN p_product pproduct3_
    ON pproductpr0_.p_product_id = pproduct3_.p_product_id
WHERE  pproductpr0_.p_product_id = ‘C07C25F3621A4B509E9DCE111812B7BA’
AND EXISTS(
  SELECT pproductty2_.p_ptp_classify_id
  FROM  p_product_type_prop_classify pproductty2_
  WHERE  pproductty1_.p_ptp_classify_id = pproductty2_.p_ptp_classify_id
  AND pproductty2_.p_ptp_classify_id = ‘8a8a94e55162a9db015162b123470065’)
ORDER BY pproductty1_.p_ptype_prop_order;

p_product_prop经过pproductpr0_.p_product_id = ‘C07C25F3621A4B509E9DCE111812B7BA’
过滤之后就是个小的结果集

 再EXISTS的时候,效率也很高

 最终要的是能用上pproductpr0_.p_product_id的单键索引

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109088.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月13日 下午6:00
下一篇 2021年9月13日 下午7:00


相关推荐

  • JSP入门教程(4)[通俗易懂]

    使用脚本在有些地方,你大概要加一些好的,成熟的程序到你的JSP页里,JSP的标签虽然很强大,但是完成某些工作还是比较费力的困难的。这时你可以使用脚本语言段来补充JSP标签。使用的JSP引擎是支持脚本语言的,SUN的JSP参考文说明,必须使用Java程序语言来编写脚本,但是其他第三方的JSP引擎允许使用其他语言来写脚本程。如何增加脚本首先,你必须了解一些增加脚本元素到JSP页中的一些基本规则

    2022年4月10日
    48
  • ROS中启动超声波雷达节点「建议收藏」

    ROS中启动超声波雷达节点「建议收藏」超声波雷达型号为KS136,KS136使用I2C接口与主机通信,自动响应主机的I2C控制指令。指令为8位数据,指令发送流程如下,先接收I2C控制指令,寄存器2接收控制指令,选择超声波探头号(因为主控板接12个收发一体式防水探头,每个探头独立工作,每个探头占据8位地址,分别对应8种不同的数据收发方式),流程图如下所示:超声波与主控之间通过串口通信代码如下: r…

    2025年9月7日
    8
  • 161018–NOIP模拟

    161018–NOIP模拟

    2022年2月21日
    52
  • Logstash详解之——filter模块[通俗易懂]

    Logstash详解之——filter模块[通俗易懂]Logstash详解之——filter模块

    2022年4月20日
    45
  • 分布式事务 java代码_Java分布式事务概念与实现示例[通俗易懂]

    分布式事务 java代码_Java分布式事务概念与实现示例[通俗易懂]在java中有如下三种事务,简单的JDBC级的事务JTA-在EJB环境下,用户得到事务并进行控制CMP-完全由容器控制事务,用户通过Bean配置文件来定义事务行为二三种都支持分布式事务,但只支持Java环境下的分布式事务。下面讨论如何在Java程序里实现分布式事务,即在同一个事务里访问多个数据源。实际上就是如何使用JTA.这里假设使用oracle数据库,使用webLogic部署应用,所要做…

    2022年5月8日
    51
  • 解析土豆视频下载地址以及硕鼠网原理

    解析土豆视频下载地址以及硕鼠网原理

    2021年8月20日
    132

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号