需要根据EXPLAIN PLAN加快我的UPDATE QUERY

时间:2015-12-18 14:17:34

标签: sql oracle indexing sql-execution-plan

我正在使用临时表更新我的表数据,它需要永远,但仍未完成。所以我收集了关于查询的解释计划。有人可以告诉我如何调整查询或在它们上构建索引。

查询:

UPDATE w_product_d A
SET A.CREATED_ON_DT = (SELECT min(B.creation_date)
                       FROM mtl_system_items_b_temp B
                       WHERE  to_char(B.inventory_item_id) = A.integration_id
                       and B.organization_id IN ('102'))
where A.CREATED_ON_DT is null;

解释计划:

Plan hash value: 1520882583

-----------------------------------------------------------------------------------------------
| Id  | Operation           | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT    |                         | 47998 |   984K|    33M  (2)|110:06:25 |
|   1 |  UPDATE             | W_PRODUCT_D             |       |       |            |          |
|*  2 |   TABLE ACCESS FULL | W_PRODUCT_D             | 47998 |   984K|  9454   (1)| 00:01:54 |
|   3 |   SORT AGGREGATE    |                         |     1 |    35 |            |          |
|*  4 |    TABLE ACCESS FULL| MTL_SYSTEM_ITEMS_B_TEMP |  1568 | 54880 |   688   (2)| 00:00:09 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("A"."CREATED_ON_DT" IS NULL)
   4 - filter("B"."ORGANIZATION_ID"=102 AND TO_CHAR("B"."INVENTORY_ITEM_ID")=:B1)

Note
-----
   - dynamic sampling used for this statement (level=2)

1 个答案:

答案 0 :(得分:0)

尝试MERGE声明。它可能会更快,因为它可以一次读取所有mtl_system_items_b_temp条记录,而不是为w_product_d中的每一行重复读取它们。

此外,您的表格看起来像是Oracle e-BS环境的一部分。在此类环境中的MTL_SYSTEM_ITEMS_B中,INVENTORY_ITEM_IDORGANIZATION_ID列为NUMBER。您似乎在表中使用VARCHAR2。如果您未在查询中使用正确的数据类型,则会引发性能问题,因为Oracle必须隐式转换为正确的数据类型,并且这样做会失去在列上使用索引的能力。因此,请确保您的查询根据其数据类型正确处理每个列。 (例如,如果某列是NUMBER使用COLUMN_X = 123而不是COLUMN_X = '123'

这里是MERGE示例:

MERGE INTO w_product_d t
USING ( SELECT to_char(inventory_item_id) inventory_item_id_char, min(creation_date) min_creation_date
        FROM   mtl_system_items_b_temp 
        WHERE  organization_id IN ('102')  -- change this to IN (102) if organization_id is a NUMBER field!
      ) u
ON ( t.integration_id = u.inventory_item_id_char AND t.created_on_dt IS NULL )
WHEN MATCHED THEN UPDATE SET t.created_on_dt = nvl(t.created_on_date, u.min_creation_date)  -- NVL is just in case...