zoukankan      html  css  js  c++  java
  • 【DB2】SQL优化

    温馨提醒:

    TMP_007数据量为:409373

    1.去除在谓词列上编写的任何标量函数

    优化前:(耗时3.1s)

    SELECT START_DATE,CST_NM FROM TMP_007 WHERE YEAR(TO_DATE(START_DATE,'YYYYMMDD'))='2009'

    优化后:(耗时0.922s)

    SELECT START_DATE,CST_NM FROM TMP_007 WHERE START_DATE BETWEEN '20090101' AND '20091231'

    总结:

    DB2可以选择使用START_DATE上的列索引,但是在列上使用了函数后,DB2就无法使用列索引了,从而导致查询效率变低。


    2.去除在谓词列上编写的任何数学运算

    优化前:(耗时10.265)

    SELECT ACCT_ID,CST_ID,CONTRACT_AMT FROM TMP_007 WHERE CONTRACT_AMT*0.1 > 10000
    

    优化后:(耗时3.39s)

    SELECT ACCT_ID,CST_ID,CONTRACT_AMT  FROM TMP_007 WHERE CONTRACT_AMT > 10000/0.1
    

    总结:

    DB2查询时候,会优先选择列CONTRACT_AMT上的索引,如果直接对列CONTRACT_AMT应用数学运算,DB2就无法使用索引了。一定要做到:列本身(不加数学运算)放在操作符的一边,而所有的计算都放在另外一边。



    3.SQL语句中指定查询列

    优化前:(耗时13.15s)

    SELECT * FROM TMP_007

    优化后:(耗时2.922s)

    SELECT ACCT_ID,CST_ID,CONTRACT_AMT  FROM TMP_007

    总结:

    如果Select包含不需要的列,优化工具会选择Indexonly=’N’,这会强制DB2必须进入数据页来得到所请求的特定列,这就要求更多的I/O操作,梁歪,这些多余的列可能是某些排序的部分,这样一来就需要和传递一个更大的排序文件,相应的会使排序成本更高。



    4.尽可能不使用distinct

    优化前:(耗时0.687s)

    SELECT DISTINCT CST_ID FROM TMP_007 ;

    优化后:(耗时0.437s)

    SELECT CST_ID FROM TMP_007  GROUP BY  CST_ID;

    总结:

    在测试distinct与group by性能的过程中,在列CST_ID上添加索引后,发现group by 确实比distinct快一些,但是在数据分布比较离散的情况下使用group by ,比较集中的情况下使用distinct.表数据量较少的情况随便使用哪个都一样,不管选择谁,都要建立索引


    5.Exists、in、not in 、not exists的使用场景选择

    5.1 in跟exists的区别:

    例如:表A(小表),表B(大表)                                                                                    

    优化前:(耗时1.93s)

    select * from A where cc in(select cc from B)  -->效率低,用到了A表上cc列的索引;

    优化后:(耗时1.125s)

    select * from A where exists(select cc from B where cc=A.cc)  -->效率高,用到了B表上cc列的索引。

    相反的,                                                                                 

    优化前:(耗时1.9s)

    select * from B where cc in(select cc from A)  -->效率高,用到了B表上cc列的索引

    优化后:(耗时1.0s)

    select * from B where exists(select cc from A where cc=B.cc)  -->效率低,用到了A表上cc列的索引。

    总结:

    in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的。如果查询的两个表大小相当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in;

    简称:子大Exists,子小in

    5.2 not in 与 not exists区别:

    如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。


    6.尽可能使用union all来代替union

    优化前:(耗时15.344s)

    SELECT ACCT_ID,CST_NAME FROM TMP_007
    UNION
    SELECT ACCT_ID,CUST_NM FROM TMP_008

    优化后:(耗时2.719s)

    SELECT ACCT_ID,CST_NAME FROM TMP_007
    UNION ALL
    SELECT ACCT_ID,CUST_NM FROM TMP_008

    总结:

    在union中,DB2最后会自动执行一个排序来消除重复值,这样是很耗费资源的,所以在不需要去重复的情况下,尽可能使用UNION ALL 代替union


    N.模板

    优化前:(耗时3.1s)


    优化后:(耗时0.922s)


    总结:




  • 相关阅读:
    react15
    react14
    react13
    react12
    react11
    【医学图像处理】提取勾画
    【图像分割 损失函数】Loss functions for image segmentation
    【批处理】子文件夹压缩包和指定后缀名文件
    【版本更新】PerfDog 5.0强势来袭,业界首创支持GPU详细信息采集与众多升级优化
    感知行业风向,掌握质量脉动,腾讯WeTest发布《2020移动游戏质量白皮书》
  • 原文地址:https://www.cnblogs.com/OliverQin/p/10097601.html
Copyright © 2011-2022 走看看