gpt4 book ai didi

sql - Oracle 查询中避免更新字段的最佳方法是什么(如果未更改)?

转载 作者:行者123 更新时间:2023-12-01 10:41:49 25 4
gpt4 key购买 nike

我只是想知道我可以在 Oracle 查询中使用的最佳方法,以避免更新未更改的字段?

Update xtab1 set xfield1='xxx' where xkey='123';

在性能方面,如果 xfield1 的现有值为“xxx”,则不应调用此更新的最佳方式是什么。

选项 1:

  • step1:Invoke a SELECT to Fetch the value of xfield1
  • step2:If the above value is not 'xxx', then only invoke UPDATE

选项 2:

  • Invoke update as below:

    Update xtab1 set xfield1='xxx' where xkey='123' and xfield1 <> 'xxx'

请让我知道以上两种方法中哪一种是最佳和理想的方法,或者是否有其他理想的方法可以使用?

感谢您的帮助

最佳答案

Update xtab1 set xfield1='xxx' where xkey='123' and xfield1 <> 'xxx'

过滤谓词 在进行更新之前应用。因此,我会选择选项 2,让 Oracle 为您完成这项工作,而不是手动执行以首先过滤掉行。此外,在两个不同的步骤中执行此操作将是一项开销。行的过滤应该是同一步骤的一部分。

关于性能,我认为索引会发挥重要作用。

你可以测试一下看看:

没有索引

选项 1

SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 931696821

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 5 | 35 | 3 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | TABLE ACCESS FULL| T | 5 | 35 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------

2 - filter("DEPTNO"=20)

14 rows selected.

SQL>

选项 2

SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20 AND sal<>9999;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 931696821

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4 | 28 | 3 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | TABLE ACCESS FULL| T | 4 | 28 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------

2 - filter("DEPTNO"=20 AND "SAL"<>9999)

14 rows selected.

有索引

SQL> CREATE INDEX t_idx ON t(deptno,sal);

Index created.

选项 1

SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1175576152

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 5 | 35 | 1 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | INDEX RANGE SCAN| T_IDX | 5 | 35 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------

2 - access("DEPTNO"=20)

14 rows selected.

SQL>

选项 2

SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20 AND sal<>9999;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1175576152

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4 | 28 | 1 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | INDEX RANGE SCAN| T_IDX | 4 | 28 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------

2 - access("DEPTNO"=20)
filter("SAL"<>9999)

15 rows selected.

SQL>

因此,在所有情况下,在选项 2 中,应用过滤器("SAL"<>9999)

关于sql - Oracle 查询中避免更新字段的最佳方法是什么(如果未更改)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29619786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com