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联结,同时要注意符合第一设计范式啊,否则即使数据很小,速度也很慢。
  • 相关阅读:
    SQL INNER JOIN
    SQL JOIN
    SQL OUTER JOIN
    SQL CROSS JOIN
    SQL 基础:Select语句,各种join,union用法
    Morton Code
    vs 字体
    sql 语言
    sqllite3
    linux怎么区别文本文件和二进制文件
  • 原文地址:https://www.cnblogs.com/zping/p/1335144.html
Copyright © 2011-2022 走看看