Oracle 分布式查询优化

Oracle 分布式查询优化

适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

分布式查询优化[1]:

场景

  • DB Link 查询
  • 跨库 JOIN
  • 数据同步

2.1 创建

-- 公共
CREATE PUBLIC DATABASE LINK remote_db 
  CONNECT TO user IDENTIFIED BY ****** 
  USING 'remote_tns';

-- 私有
CREATE DATABASE LINK remote_db 
  CONNECT TO user IDENTIFIED BY ****** 
  USING 'remote_tns';

2.2 查询

SELECT * FROM employees@remote_db;
SELECT * FROM local_emp l, remote_emp@remote_db r WHERE l.id = r.id;

3. 优化策略

3.1 减少远程访问

-- 1. 批量查询
SELECT * FROM big_table@remote_db WHERE date_col >= :start_date;

-- 2. 本地过滤
-- 避免:SELECT * FROM remote_emp@db; -- 拉取所有
-- 推荐:SELECT * FROM remote_emp@db WHERE id IN (1, 2, 3);

3.2 推送 vs 拉取

-- 推送:本地过滤结果推送
SELECT * FROM remote_emp@db r
WHERE r.id IN (SELECT l.id FROM local_emp l WHERE l.dept = 10);

-- 拉取:远程结果拉取
SELECT * FROM local_emp l, remote_emp@db r WHERE l.id = r.id;

3.3 DRIVING_SITE

-- 远程站点执行
SELECT /*+ DRIVING_SITE(r) */ * 
FROM local_emp l, remote_emp@db r 
WHERE l.id = r.id;

4. JOIN 优化

4.1 Hash Join

-- 小表在本地
SELECT /*+ USE_HASH(l r) */ *
FROM local_small l, remote_big@db r
WHERE l.id = r.id;

4.2 Nested Loop

-- 远程小表
SELECT /*+ USE_NL(r) LEADING(r) */ *
FROM remote_small@db r, local_big l
WHERE r.id = l.id;

4.3 本地执行

-- 拉取远程到本地
SELECT /*+ NO_MERGE(r) */ *
FROM TABLE(SELECT CURSOR(...) FROM remote@db) r, local l;

5. 物化视图

5.1 远程数据本地化

CREATE MATERIALIZED VIEW mv_remote_emp
  REFRESH COMPLETE ON DEMAND
  START WITH SYSDATE NEXT SYSDATE + 1
AS
SELECT * FROM remote_emp@remote_db;

5.2 FAST Refresh

-- 远程 MV 日志
CREATE MATERIALIZED VIEW LOG ON remote_emp;

-- 本地 MV
CREATE MATERIALIZED VIEW mv_remote_emp
  REFRESH FAST ON DEMAND
AS
SELECT * FROM remote_emp@remote_db;

详细见:Oracle 物化视图性能优化


6. 分布式事务

6.1 两阶段提交

-- 2PC
SET TRANSACTION NAME 'my_txn';

INSERT INTO local_table VALUES (...);
INSERT INTO remote_table@db VALUES (...);

COMMIT;
-- Prepare + Commit

6.2 监控

-- 悬挂事务
SELECT * FROM dba_2pc_pending;
SELECT * FROM dba_2pc_neighbors;

-- 强制提交/回滚
COMMIT FORCE 'local.tran.id';
ROLLBACK FORCE 'local.tran.id';

6.3 优化

  • 减少分布式事务
  • 单库事务优先
  • 应用层补偿

7. 网络优化

7.1 SDU

# sqlnet.ora
DEFAULT_SDU_SIZE = 32767

7.2 Array Fetch

-- PL/SQL BULK
DECLARE
  TYPE t_emp IS TABLE OF employees%ROWTYPE;
  v_emp t_emp;
BEGIN
  SELECT * BULK COLLECT INTO v_emp FROM employees@remote_db;
  FORALL i IN 1..v_emp.COUNT
    INSERT INTO local_emp VALUES v_emp(i);
END;
/

详细见:Oracle 网络性能优化


8. 数据同步

8.1 GoldenGate

  • 实时复制
  • 异构数据库

详细见:Oracle GoldenGate 实时复制

8.2 Streams

  • 数据流
  • 异步

8.3 物化视图

  • 定时同步
  • 简单

9. 监控

SELECT * FROM dba_db_links;
SELECT * FROM v$dblink;

9.2 网络等待

SELECT event, total_waits FROM v$system_event 
WHERE event LIKE 'SQL*Net%';

10. 常见坑与排错

10.1 ORA-02019

-- connection description for remote database not found
-- 1. 检查 TNS
-- 2. 检查 DB Link

10.2 性能慢

-- 1. 拉取过多数据
-- 2. 减少 JOIN
-- 3. 物化视图
-- 4. DRIVING_SITE

10.3 分布式事务悬挂

-- 1. dba_2pc_pending
-- 2. FORCE COMMIT/ROLLBACK
-- 3. PURGE
EXEC DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('...');

11. 最佳实践

  1. 减少远程访问:批量
  2. DRIVING_SITE:远程执行
  3. 物化视图本地化:性能
  4. Array Fetch:批量
  5. 大 SDU:减少往返
  6. 避免分布式事务:复杂
  7. GoldenGate 同步:实时
  8. 监控网络:等待
  9. 测试网络:延迟
  10. 应用层补偿:最终一致

12. 参考资料

[1] Oracle Database Administrator’s Guide 19c, “Distributed Database” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-distributed-databases.html