Oracle 分布式查询优化
Oracle 分布式查询优化
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
分布式查询优化[1]:
场景:
- DB Link 查询
- 跨库 JOIN
- 数据同步
2. DB Link
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
- 实时复制
- 异构数据库
8.2 Streams
- 数据流
- 异步
8.3 物化视图
- 定时同步
- 简单
9. 监控
9.1 DB Link 使用
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. 最佳实践
- 减少远程访问:批量
- DRIVING_SITE:远程执行
- 物化视图本地化:性能
- Array Fetch:批量
- 大 SDU:减少往返
- 避免分布式事务:复杂
- GoldenGate 同步:实时
- 监控网络:等待
- 测试网络:延迟
- 应用层补偿:最终一致
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