【问题标题】:oracle GTT Vs IN clause literalsoracle GTT Vs IN 子句文字
【发布时间】:2020-08-15 07:05:29
【问题描述】:

有一个查询,其中 GTT(few 100 Recs) 内部与主表连接。

ex :
insert into table1 select col2,col3 from gtt,maintable where gtt.id=maintable.id    .. few other joins 

查询加载到 table1 大约需要 15-20 分钟,但是当我在查询中传递那些 GTT 表值硬编码时,它将在 4-5 分钟内完成。

这里的主要区别是什么,有什么方法可以使用 GTT 来提高性能。(不能避免 GTT,因为有时值可能超过 1000)

在下面尝试过 1. 删除了内连接并用 IN 子句替换( where IN (select id from GTT),但没有运气 2. 添加 push_subq 和 unnest HINT with subquery(option 1) ,但没有运气

计划


with GTT

|  74 | NESTED LOOPS                      |                           
|  75 |  BUFFER SORT                      |                           
|  76 |   PX RECEIVE                      |                           
|  77 |    PX SEND BROADCAST              | :TQ20006                  
|  78 |     SORT UNIQUE                   |                           
|  79 |      PX RECEIVE                   |                           
|  80 |       PX SEND HASH                | :TQ20005                  
|  81 |        PX BLOCK ITERATOR          |                           
|  82 |         TABLE ACCESS STORAGE FULL | STAGE_GTT    
|  83 |  PX PARTITION HASH ITERATOR       |                           
|  84 |   TABLE ACCESS STORAGE FULL       | EXP_TABLE                 =====>103GB == cell offloaded 95%  




With literal 

 129 |  PX SEND HASH                          | :TQ20006              
 130 |   HASH JOIN                            |                       
 131 |    PX PARTITION HASH INLIST            |                       
 132 |     VIEW                               |                       
 133 |      TABLE ACCESS STORAGE FULL         | EXP_TABLE       ====(27GB ) ==cell offloaded 98%


【问题讨论】:

  • JOIN 中涉及的列是否被索引?
  • 您是否介意提供完整的查询并描述表以及索引和约束。还有多少记录在maintable中。如果你能展示数据样本,那也很棒。
  • @Littlefoot,是的,它有索引,GTT 和主表都有,但是没有使用主表索引,但分区在同一列上。
  • @VN'sCorner, GTT=250 Records, maintable=few Million , GTT and main table join =4777100 后,查询太大太复杂,这里不能过去。 GTT 有一个索引,但我们正在执行全表扫描,主表的索引很少,但我们再次执行 FTS,但连接在分区键列上

标签: plsql oracle11g


【解决方案1】:

好吧,这只是在黑暗中的一个镜头。如果你能回应我的cmets可以即兴发挥。

insert into table1 select col2,col3 from gtt 
        where exists (select 1 from maintable 
                      where gtt.id=maintable.id    
                      .. few other joins)

假设:col2,col3 来自 gtt。

【讨论】:

  • 我试过:insert into table2 select col2,col3 from Maintable where id in (select id from GTT),但没有帮助,
  • 那么我的假设是错误的。 col2,col3 不能来自 GTT,因为返回的记录是 4777100。它们应该来自 maintable,因为连接中没有其他表。
  • 我相信您提到的 4-5 分钟是作为连接中使用的单个“id”值的文字传递的。只运行 select * from maintable 需要多长时间?如果您使用的是编辑器,则它是您滚动到最后一条记录所用的时间。您能检查一下吗?
  • 无法从主表中运行 select *。它是一个分区表,有数百万条记录。
  • 知道了,你介意分享一下表结构,至少是连接中涉及的列以及分区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 2011-07-21
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
相关资源
最近更新 更多