【问题标题】:performance issues using UNION , multiple columns使用 UNION 的性能问题,多列
【发布时间】:2017-12-10 04:53:58
【问题描述】:

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

使用 UNION 的性能问题

    SELECT
                    store.store_name name,
                    store.block_id block_id,
                    store.marker flag,
                    substr('A',1,1) store_type,
                    substr(area.area_code,1,5) area_code,
                    substr(area.area_name,1,5) area_name
    FROM  store , area
            where store.store_id = area.store_id
            and store.block_id = area.block_id
    UNION
     SELECT
                    store.store_name name,
                    store.block_id block_id,
                    store.marker flag,
                    substr('A',1,1) store_type,
                    substr(market.market_code,1,5) area_code,
                    substr(market.market_area,1,5) area_name
    FROM  store , market
            where store.store_id = market.store_id 
            and store.block_id =market.block_id;                                

                 | 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))

【问题讨论】:

  • 首先:查询似乎有点奇怪。一个表应该代表一些实体,比如用户、员工、部门、电影等等。所以 tab2 和 tab3 代表不同的实体,你为什么要把结果粘在一起呢?也许您应该在这里不那么抽象并告诉我们表格包含什么,然后我们可能会提出更改建议。照原样,查询没问题,无法真正优化。
  • 你需要UNION的去重,还是可以改用UNION ALL
  • @ThorstenKettner 更新查询
  • @jarlh 我也需要消除重复项
  • substr('A',1,1)'A'。如果您对子字符串感兴趣(例如substr(area.area_code,1,5)),这表明您应该更好地将字符串部分存储在单独的列中。区号、区名、市场代码和市场名称的前五个字符分别代表什么?

标签: sql oracle oracle11g oracle12c


【解决方案1】:

一般情况下,UNION 不会导致 FTS。 FTS 由优化器决定,如果它认为它可以更好地扫描所有行而不是索引访问,然后是表访问。所以我看到了这个问题的一些问题:

  1. 没有数据子集,这意味着你想要所有的行 无论如何,所以如果是这样的话,那么 FTS 很可能是 成本最低的选择。

  2. 没有数据子集,索引是唯一可能的方法 使用的是如果“连接列”是至少表中的索引 遵循 FTS(在某些情况下,您可能会寻找较小的表 是 FTS,然后是基于索引访问更大的表 连接条件列是索引)。

  3. 您没有指明表大小或索引是什么; 了解基数等对于 SQL 调优至关重要。

此外,如果您拥有 Diagnostics+Tuning Pack 的许可,您可以通过 SQL Tuning Advisor 运行 SQL,并查看该工具提供的调优建议。

【讨论】:

    猜你喜欢
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    相关资源
    最近更新 更多