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

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

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

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

很多人喜欢在优化 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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux命令杀进程脚本_shell脚本获取进程号并杀死进程

    linux命令杀进程脚本_shell脚本获取进程号并杀死进程由于代码调试进程一直存在需要手动杀死,比较费时,写个小脚本节省下时间#viclear.sh​!/bin/bashecho”$1″pid=`ps-ef|grep$1|grep-vgrep|grep-vbash|awk'{print$2}’`echo”$pid”if[-n”$pid”]thenecho”kill-9pid:$pid”kill-9$pidfi[点击并拖拽以移动]​#chmod.

    2022年9月29日
    2
  • 《高可用MySQL》2 – 单机版MySQL主从配置「建议收藏」

    《高可用MySQL》2 – 单机版MySQL主从配置

    2022年2月2日
    36
  • 数据挖掘领域十大经典算法之—EM算法

    数据挖掘领域十大经典算法之—EM算法相关文章:数据挖掘领域十大经典算法之—C4.5算法(超详细附代码)数据挖掘领域十大经典算法之—K-Means算法(超详细附代码)数据挖掘领域十大经典算法之—Apriori算法数据挖掘领域十大经典算法之—EM算法数据挖掘领域十大经典算法之—PageRank算法数据挖掘领域十大经典算法之—AdaBoost算法(超详细附代码)数据挖掘领域十大经…

    2022年5月3日
    51
  • idea 全局查找快捷键

    idea 全局查找快捷键对的

    2022年6月29日
    86
  • 重装系统error16_error怎么解决

    重装系统error16_error怎么解决 初看这个错误,让我有点头大,因为我用客户端调用,它竟然告诉我服务器拒绝接收.上网上看了很多资料(90%是英文).各说其词,结果还是无果而终.终于功夫不负有心人,终于在不经意间看到了一个老外的陈词: packagecn.sss_grid.mis.action.gydq.service.client;//importcom.sss.util.JDom;importjava.

    2022年9月13日
    3
  • MyBatis面试题总结「建议收藏」

    MyBatis面试题总结「建议收藏」啃下MyBatis源码-MyBatis面试题总结1.概念/使用方法向的问题1.1什么是Mybatis?1.2为什么说Mybatis是半ORM框架?/与Hibernate有哪些不同?1.3Mybaits的优点?1.4MyBatis框架的缺点?1.5#{}和${}的区别?1.6怎么解决实体类中的属性名和表中的字段名不一样的问题?1.7在mapper中如何传递多个参数?…

    2022年6月11日
    26

发表回复

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

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