从本地数据库更新远程数据库时出现性能问题
Performance issue while Update remote database from local database
- 我试图通过触发器从本地数据库更新远程 table(dblink)。
我的费用在24990左右。Table数据统计近3032965。
UPDATE remote_table
SET ip_stats = (
CASE
WHEN :NEW.ip_stats IN (22,30,) THEN 'Non-Network'
WHEN :NEW.ip_stats IN (23,31,182) THEN 'Cancel'
WHEN :NEW.ip_stats IN (24,32) THEN 'file'
WHEN :NEW.ip_stats IN (26,34) THEN 'online'
WHEN :NEW.ip_stats IN (63) THEN 'decrease'
WHEN :NEW.ip_stats IN (64) THEN 'increase'
END) ,
ip_comments = (
CASE :NEW.ip_commts
WHEN 154 THEN 'increase'
WHEN 155 THEN 'previous'
WHEN 156 THEN 'hardware'
WHEN 157 THEN 'software'
END) ,
feedback = :NEW.feedback ,
changed_by = :NEW.changed_by ,
create_dt = :NEW.create_dt ,
status = 'Y' ,
sum_amount = NVL (:NEW.net_amount ,0)
WHERE ID = :NEW.new_key;
下面是更新语句的解释计划。
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
---------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT REMOTE| | 1 | 195 | 24990 (2)| 00:05:00 | |
| 1 | UPDATE | remote_table | | | | | rmt |
|* 2 | TABLE ACCESS FULL | remote_table | 1 | 195 | 24990 (2)| 00:05:00 | rmt |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TO_NUMBER("A1"."ID")=123478)
Note
-----
- fully remote statement
- 此外,当我为此使用 count(*) 时,remote_table 它的成本与 24990 相同。
注意: 我在 select 语句中使用 INDEX
提示如下,但它不起作用
SELECT /*+INDEX (a Column_index_name)*/ COUNT(*) FROM remote_table a WHERE a.ID = 123478;
下面是 select count(*) 语句的解释计划。
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT REMOTE| | 1 | 9 | 24990 (2)| 00:05:00 | |
| 1 | SORT AGGREGATE | | 1 | 9 | | | |
|* 2 | TABLE ACCESS FULL | remote_table | 1 | 9 | 24990 (2)| 00:05:00 | rmt |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TO_NUMBER("A1"."ID")=123478)
Note
-----
- fully remote statement
任何人都可以就如何处理这个问题提出建议吗?
注意列格式。您的列 ID
是 VARCAHR2
,因此您应该这样查询它。
您的谓词 ID = 123478
进行了一个 +隐式转换* 禁止索引访问
使用ID = '123478'
,这将启用索引访问。
带有模拟 table 和 id varchar2(10)
的示例
SELECT * FROM tab a WHERE a.ID = 23478;
导致执行计划(为简洁起见删减)
|* 1 | TABLE ACCESS FULL| TAB | 1081 | 2120K| 27171 (1)| 00:00:02 |
1 - filter(TO_NUMBER("A"."ID")=23478)
但是查询使用了正确的格式文字
SELECT * FROM tab a WHERE a.ID = '23478';
有正确的计划
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2009 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB | 1 | 2009 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TAB_IDX | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."ID"='23478')
- 我试图通过触发器从本地数据库更新远程 table(dblink)。 我的费用在24990左右。Table数据统计近3032965。
UPDATE remote_table
SET ip_stats = (
CASE
WHEN :NEW.ip_stats IN (22,30,) THEN 'Non-Network'
WHEN :NEW.ip_stats IN (23,31,182) THEN 'Cancel'
WHEN :NEW.ip_stats IN (24,32) THEN 'file'
WHEN :NEW.ip_stats IN (26,34) THEN 'online'
WHEN :NEW.ip_stats IN (63) THEN 'decrease'
WHEN :NEW.ip_stats IN (64) THEN 'increase'
END) ,
ip_comments = (
CASE :NEW.ip_commts
WHEN 154 THEN 'increase'
WHEN 155 THEN 'previous'
WHEN 156 THEN 'hardware'
WHEN 157 THEN 'software'
END) ,
feedback = :NEW.feedback ,
changed_by = :NEW.changed_by ,
create_dt = :NEW.create_dt ,
status = 'Y' ,
sum_amount = NVL (:NEW.net_amount ,0)
WHERE ID = :NEW.new_key;
下面是更新语句的解释计划。
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
---------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT REMOTE| | 1 | 195 | 24990 (2)| 00:05:00 | |
| 1 | UPDATE | remote_table | | | | | rmt |
|* 2 | TABLE ACCESS FULL | remote_table | 1 | 195 | 24990 (2)| 00:05:00 | rmt |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TO_NUMBER("A1"."ID")=123478)
Note
-----
- fully remote statement
- 此外,当我为此使用 count(*) 时,remote_table 它的成本与 24990 相同。
注意: 我在 select 语句中使用 INDEX
提示如下,但它不起作用
SELECT /*+INDEX (a Column_index_name)*/ COUNT(*) FROM remote_table a WHERE a.ID = 123478;
下面是 select count(*) 语句的解释计划。
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT REMOTE| | 1 | 9 | 24990 (2)| 00:05:00 | |
| 1 | SORT AGGREGATE | | 1 | 9 | | | |
|* 2 | TABLE ACCESS FULL | remote_table | 1 | 9 | 24990 (2)| 00:05:00 | rmt |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TO_NUMBER("A1"."ID")=123478)
Note
-----
- fully remote statement
任何人都可以就如何处理这个问题提出建议吗?
注意列格式。您的列 ID
是 VARCAHR2
,因此您应该这样查询它。
您的谓词 ID = 123478
进行了一个 +隐式转换* 禁止索引访问
使用ID = '123478'
,这将启用索引访问。
带有模拟 table 和 id varchar2(10)
SELECT * FROM tab a WHERE a.ID = 23478;
导致执行计划(为简洁起见删减)
|* 1 | TABLE ACCESS FULL| TAB | 1081 | 2120K| 27171 (1)| 00:00:02 |
1 - filter(TO_NUMBER("A"."ID")=23478)
但是查询使用了正确的格式文字
SELECT * FROM tab a WHERE a.ID = '23478';
有正确的计划
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2009 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB | 1 | 2009 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TAB_IDX | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."ID"='23478')