zoukankan      html  css  js  c++  java
  • SQL 语句优化中间表的使用优化

           上周五,公司的同事,从客户那边回来,说一个人员选择页面很慢,页面打开需要15s左右,后来自己也试了一下,也的确需要比较长的时间,客户反应比较强烈。

          通过DMV查出缓慢的两个语句如下:

    语句一:

    Code

      语句二:

    Code

     

        查询的两个表的数据量: 表humres:  1920 行 ,  191次 IO  

                                       表orgunitlink: 256 行, 11 次IO 

        最大表才不到2000行数据,查询为何如此慢。看看执行计划:

       查询开销:

    (20 行受影响)
    表 
    'Worktable'。扫描计数 1,逻辑读取 8270 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    表 
    'humres'。扫描计数 2,逻辑读取 382 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    表 
    'orgunitlink'。扫描计数 1,逻辑读取 11 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

          这时发现:由于采用“%”来模糊查询,系统无法使用hash联结算法,采用嵌套循环算法。使得IO次数,多了8000个IO。

          这里的col1,orgids :多个32位id,中间用","号隔开串, 如:'4028b14f175788140117581e030d00c7,4028b14f17578814011757f6131d0065'

          一开始,我的思路是通过函数,将列col1,orgids中通过‘,’分开的函数隔离开来,将一行变多行,使其使用hash联结,但是后来发现虽然使用了hash联结

    ,但在系统在col1,orgids转换成多列时也很耗时间,最后想了一个更好的办法:

         通过触发器建立中间表,将orgids,col1存放到另一个表中,由于这里都是一些基本数据,人员和机构,一般的变化的频率不高,也就一两天修改一次就很了不起了。建立触发器对数据库其他性能影响很小。全部代码和改写的SQL如下:  

    Code

        通过以上的修改优化,点开页面速度很快

        总结:     

        这里,由于前期表设计的不合理,造成速度很慢,而且在业务逻辑不变,程序不变的情况下,是一个比较择中的优化方法。同时在后面设计表时要,注意让SQL优化器能使用到Hash联结,同时要注意符合第一设计范式啊,否则即使数据很小,速度也很慢。
  • 相关阅读:
    HDU 5912 Fraction (模拟)
    CodeForces 722C Destroying Array (并查集)
    CodeForces 722B Verse Pattern (水题)
    CodeForces 722A Broken Clock (水题)
    CodeForces 723D Lakes in Berland (dfs搜索)
    CodeForces 723C Polycarp at the Radio (题意题+暴力)
    CodeForces 723B Text Document Analysis (水题模拟)
    CodeForces 723A The New Year: Meeting Friends (水题)
    hdu 1258
    hdu 2266 dfs+1258
  • 原文地址:https://www.cnblogs.com/zping/p/1335144.html
Copyright © 2011-2022 走看看