使用left join巧妙优化not in关联子查询

某交通项目,tb_case 2万多条记录,tb_carout

1 使用原查询语句:

 SELECT TB_CASE.CASENO AS CASENO,TB_CASE.LAWGROUP AS LAWGROUP,S1.ROLE_NAME AS LGNAME,TB_CASE.CARPARK AS CARPARK,S2.ROLE_NAME AS CARPARKNAME,TB_CASE.LAWTIME AS LAWTIME,

TB_CASE.CARTYPE AS CARTYPE,TB_CASE.CARNO AS CARNO,TB_CASE.STATUS AS STATUS,TB_CASE.IS_CLONE AS IS_CLONE,TB_CASE.BCFS AS BCFS FROM TB_CASE,SYS_ROLE S1, SYS_ROLE S2

WHERE

((NOT(TB_CASE.CASENO IN (SELECT TB_CAROUT.CASENO FROM TB_CAROUT WHERE ((TB_CAROUT.STATUS = '25') AND (TB_CAROUT.SYMBOL <> 9))))) AND (TB_CASE.LAWGROUP = S1.ROLE_ID) AND (TB_CASE.CARPARK = S2.ROLE_ID));

查询时间:为88s。

 查询语句都使用了not in语句过滤外层查询表(父表)。

 查询计划如下:

QUERY PLAN 
Loop arti Join 7 om time=oeeoi 
 Join Filter. = TB_CPROUT.CASENO) OR (18_cgse CASENO IS NULL) OR UB_CAROUTCASENO IS NULL)) 
   ->Nested Loop (cost=O.OO .12636.41 rows-17466 width-520) (actual time-0_025 84.242 rows-1745B loops-I) 
       ->Nested Loop (actual timezo.01g .11D116 loops-I) 
          ->Seq scan on TB_CASE (cost=o.oo..36X6.66 rows-1 7466 (actual 2.169 rows-17466 loops-I) 
          ->Index scan using on sys_ROLE Sl rows-I Width2436) (actual time-0 003_.0.003 rows=l loops:17466) 
            Index Sl 
       ->Index scan using on SYS_ROLES2 (cost-0.00_0.27 rows-I width-436) (actual time-0.002_.0.003 rcwvs=l loops-1 7466) 
            Index Cond_ (TB_CASE CARPARK= 82 ROLE_IO) 
  ->Materialize (cost=61 ,gg..787.go rows—I aggl width-1 (actual time=O.OOO..I .882 rows=8723 loops—17458) 
         ->seq scan on TB_CAROUT (cost-0 00.601.00 rcnws=laggl width—1 7) (actual time-DOI rows=16gg1 loops-I) 
            Filter ((STATUg AND (SYMBOL g)) 
Total runtime. 88648.766 ms 

    nested loop

      从tb_carout表抽一条记录,遍历tb_case表查找匹配记录,然后从tb_carout表抽下一条,遍历ta_case表,就是一个二重循环

3 使用left join 改写sql

SELECT T1.CASENO AS CASENO,T1.LAWGROUP AS LAWGROUP,S1.ROLE_NAME AS LGNAME,T1.CARPARK AS CARPARK,S2.ROLE_NAME AS CARPARKNAME,

T1.LAWTIME AS LAWTIME,T1.CARTYPE AS CARTYPE,T1.CARNO AS CARNO,T1.STATUS AS STATUS,T1.IS_CLONE AS IS_CLONE,

T1.BCFS AS BCFS FROM TB_CASE T1

left join TB_CAROUT T2 on T1.CASENO=T2.CASENO AND T2.STATUS='25' AND T2.SYMBOL!=9

left join SYS_ROLE S1 ON T1.LAWGROUP=S1.ROLE_ID

left join SYS_ROLE S2 ON T1.CARPARK=S2.ROLE_ID

where T2.CASENO IS NULL;

查询计划如下:

使用left join巧妙优化not in关联子查询

使用left join优化之后,查询时间为78ms

Hash join

      将tb_case表按连接键计算出一个hash表,然后从tb_carout表一条条抽取记录,计算hash值,根据hash到tb_case表的hash来匹配符合条件的记录,t1.caseno=t2.caseno

1 嵌套循环(nest loop):

          对于被连接的数据子集较小的情况,嵌套循环连接是较好的选择。在嵌套循环中,外表驱动内表,外表返回的每一行都要在内表中检索找到它匹配的行,因此整个查询返回的结果集不能太大(大于10000不合适),要把返回子集较小的表作为外表(驱动表),而且在内表的连接字段上一定要有索引。

2)哈希连接(hash join):

         哈希连接是大数据集连接时常用的方式,优化器使用两个表中较小的表,利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行.对优化器有很大要求。
 

上一篇:剑指offer打卡 week2


下一篇:通过函数递归,实现简单的扫雷小游戏