加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

层次查询SQL性能故障不断?给你份可靠的避坑指南!

发布时间:2019-06-08 21:14:52 所属栏目:编程 来源:蒋健
导读:近期几回碰着条理查询SQL的机能题目,团结汗青妨碍案例,汇总了一些场景connect by常见的机能妨碍范例,在本文中做个分享。 一、功效中过滤or天生树中过滤 过滤前提安排于where后,为在功效树天生完成后裁剪叶子节点;安排于connect by后,为在天生树的进程
副问题[/!--empirenews.page--]

近期几回碰着条理查询SQL的机能题目,团结汗青妨碍案例,汇总了一些场景connect by常见的机能妨碍范例,在本文中做个分享。

一、功效中过滤or天生树中过滤

过滤前提安排于where后,为在功效树天生完成后裁剪叶子节点;安排于connect by后,为在天生树的进程中裁剪子树。

频仍产生的征象是营业逻辑上着实并不必要天赋生功效树再去过滤,因为开拓职员对过滤前提安排于差异的位置(where 后,connect by后)发生的过滤结果夹杂,导致了低效的机能。

下面这个SQL就是典范案例。用户反馈,zzzz.SYS_RC_ROUTE_DETAIL表上出产情形就3000+条数据,但SQL语句运行时却跑不出来功效:

  1. select  xxxxx 
  2.   from zzzz.SYS_RC_ROUTE_DETAIL t 
  3.  where t.route_id = (select a.route_id 
  4.                        from xxx.sys_rc_route a, xxx.g_wo_base b 
  5.                       where a.route_id = b.route_id 
  6.                         and b.work_order = 'yyyyyyyyy') 
  7.  start with t.node_type = '0' 
  8. connect by nocycle prior next_node_id = node_id 

让客户运行了SQL一分钟后cancel掉,抓取了监督陈诉如下:

条理查询SQL机能妨碍不绝?给你份靠得住的避坑指南!

题目点很明明,表中nextnodeid = node_id的一再值许多,导致了海量的功效集。SQL运行的一分钟内,connect by尚未把完备的树出产完成,就已经有了3000W+数据,于是我们开始思索,在逻辑上是否有须要在构建完备的树后再过滤。

与营业部分雷同后,发明公然不必要。

以下数据可以测试下,3000行数据量,可是count(*) 会很是慢。

  1. SQL> create table test1 as 
  2. select 
  3.     mod(rownum,2)                     id, 
  4.     mod(rownum +1 ,2)                  id2 
  5. from 
  6.     dual 
  7. connect by level <= 3000 
  8. ;  2    3    4    5    6    7    8 
  9.  
  10. Table created. 
  11.  
  12. SQL> set timing on 
  13. SQL> select count(*) from test1  where id =0  start with id =0 connect by nocycle prior id = id2 ; 
  14.  
  15.   COUNT(*) 
  16. ---------- 
  17.       1500 
  18.  
  19. Elapsed: 00:09:26.88 
  20. SQL> 

功效中过滤如上所示,用了9分钟;而天生树中过滤则只用0.3s:

  1. SQL> select count(*) from test1  start with id =0 connect by nocycle prior id = id2 and id = 0 ; 
  2.  
  3.   COUNT(*) 
  4. ---------- 
  5.       1500 
  6.  
  7. Elapsed: 00:00:00.31 

许多环境下,两种写法的功效集也许是沟通的,如下:

  1. create table test2 as 
  2.  select 
  3.       rownum                     id, 
  4.       rownum +1                 id2, 
  5.       rownum + 2               id3 
  6.  from 
  7.      dual 
  8.  connect by level <= 3000; 
  9.  
  10.  SQL> select id from test2 where id3 < 10 start with id = 3 connect by nocycle prior id2 = id; 
  11.  
  12.      ID 
  13.  ---------- 
  14.       1 
  15.       2 
  16.       3 
  17.       4 
  18.       5 
  19.       6 
  20.       7 
  21.  
  22.  7 rows selected. 
  23.  
  24.  SQL> select id from test2  start with id = 1 connect by nocycle prior id2 = id and id3 <10; 
  25.  
  26.      ID 
  27.  ---------- 
  28.       1 
  29.       2 
  30.       3 
  31.       4 
  32.       5 
  33.       6 
  34.       7 
  35.  
  36.  7 rows selected. 

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读