【问题标题】:performance issues using UNION使用 UNION 的性能问题
【发布时间】:2017-12-10 03:58:13
【问题描述】:

oracle 查询中的联合导致大量 FTS(全表扫描)和高行数我可以重写此查询的更好方法吗?

            SELECT
                            tab1.a1,
                            tab1.a2 ,
                            tab2.b1,
                            tab2.b2


            FROM tab1 ,tab2
                    where tab1.aid = tab2.aid
                    and tab1.bid = tab2.bid
            UNION 
            SELECT
                            tab1.a1,
                            tab1.a2,
                            tab3.c1,
                            tab3.c2
            FROM tab1 ,tab3
                    where tab1.cid = tab3.cid
                    and tab1.bid =tab3.bid;

解释计划看起来像这样..

                 | Id  | Operation                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
                 ---------------------------------------------------------------------------------------
                 |   0 | SELECT STATEMENT              |  1845K|    61M|       |   120K  (1)| 00:00:05 |
                 |   1 |  UNION-ALL                    |       |       |       |            |          |
                 |   2 |   MERGE JOIN                  |  1719K|    57M|       | 98522   (2)| 00:00:04 |
                 |   3 |    SORT JOIN                  |  1761K|    25M|    94M| 30984   (1)| 00:00:02 |
                 |   4 |     TABLE ACCESS FULL         |  1761K|    25M|       | 21911   (1)| 00:00:01 |
                 |*  5 |    SORT JOIN                  |  1882K|    35M|   115M| 67538   (2)| 00:00:03 |
                 |   6 |     TABLE ACCESS FULL         |  1882K|    35M|       | 56061   (2)| 00:00:03 |
                 |   7 |   NESTED LOOPS                |   126K|  3699K|       | 22186   (1)| 00:00:01 |
                 |   8 |    NESTED LOOPS               |   126K|  3699K|       | 22186   (1)| 00:00:01 |
                 |   9 |     TABLE ACCESS FULL         |   126K|  1726K|       |  3232   (2)| 00:00:01 |

索引在 (tab1 (aid,bid), tab2(aid,bid) , tab3(cid,bid))

【问题讨论】:

  • 您的查询没有WHERE 子句。所以这是所有的 tab1 记录,可能还有很多很多的 tab2 和 tab3 记录。因此,全表扫描似乎是读取表的最佳方法,而不是混淆索引,最终得到大多数记录。不过,您的查询混淆了它的真正任务。 user5480949 的回答显示了一个更清晰的查询。
  • 您使用的是我们在 1980 年代使用的连接语法。甲骨文采用它很晚,但那仍然是大约 2001 年!你不应该再使用它了。改用正确的 ANSI 连接,例如from tab1 inner join tab2 on tab1.aid = tab2.aid and tab1.bid = tab2.bid.

标签: sql oracle plsql oracle11g oracle12c


【解决方案1】:
SELECT t.a1, t.a2  
FROM tab1 t
WHERE EXISTS (SELECT 1
              FROM tab2 t2
              WHERE t.aid = t2.aid
              AND t.bid = t2.bid)
OR EXISTS (SELECT 1
           FROM tab3 t3
           WHERE t.cid = t3.cid
           AND t.bid =t3.bid)

【讨论】:

  • 是的,这是编写查询的直接方式。
  • @user5480949 ,感谢您的查询,工作出色并提供正确的输出,我不知何故错过了在查询中添加 tab2 和 tab3 列并且无法弄清楚在查询中添加的位置你给了,请求请帮助我编辑查询。
  • @anudeepks:选中 tab2 和 tab3 列后,您的新查询与以前的查询完全不同。因此,您可以完全将此作为一个新请求。
  • @Thorsten Kettner 谢谢你创建一个新请求
猜你喜欢
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 2011-01-24
相关资源
最近更新 更多