我有一个数据库基础结构,我们定期(至少每天一次)将表的全部内容从源数据库复制到大约20个目标数据库。由于正在使用复制代码(我们必须使用常规的oracle查询,无法控制或直接访问源数据库) - 这会导致20个源表的源表。
有没有办法在查询中对此进行优化?我正在寻找一些基本上可以告诉oracle的东西“我将重复整理整个表格”? MySQL有myisamchk的选项,你可以告诉它对表进行排序并按排序顺序保存,但显然这里不适用于多种原因。
目前,还有一些中间表涉及(从A到B同步,然后从B到C同步。)我们可以控制中间表,所以如果有调整选项,那么这也是有用的。
通常,查询几乎都是非常简单的形式:
select a, b, c, d, e, ... z from tbl1 order by a, b, c, d, e, ... z;
我知道流,但如上所述,主要源表不在我们的控制之内,因此我们将无法在那里使用流。 (此外,这些源表每天都会从快照中完全重建,因此无论如何流都不会真正起作用。)
答案 0 :(得分:2)
您可以查看multi-table INSERT功能。它应该执行单个FULL SCAN并将插入到多个表中。考虑(10gR2):
SQL> CREATE TABLE t1 (ID NUMBER);
Table created
SQL> CREATE TABLE t2 (ID NUMBER);
Table created
SQL> INSERT ALL
2 INTO t1 VALUES (d_id)
3 INTO t2 VALUES (d_id)
4 /* your select goes here */
5 SELECT ROWNUM d_id FROM dual d CONNECT BY LEVEL <= 5;
10 rows inserted
SQL> SELECT COUNT(*) FROM t1;
COUNT(*)
----------
5
SQL> SELECT COUNT(*) FROM t2;
COUNT(*)
----------
5
您必须检查它是否适用于数据库链接。
答案 1 :(得分:0)
有助于排序问题的一些事情是在您要排序的列上有索引(如果它们已经存在,也会加入表)。您还可以创建已经排序的物化视图,Oracle将保持已排序的结果。
答案 2 :(得分:0)
您没有详细说明复制的完成方式或涉及的数据量(或者您为什么要对数据进行排序)。
如果目标是最小化对源数据库的影响,最好的办法是提取到中间文件并将文件加载到目标数据库中。排序可以在中间文件(如果是纯文本)上完成,也可以作为导出或导入目标数据库的一部分。
In source database :
create table export_emp_info
organization external
( type oracle_datapump
default directory DATA_PUMP_DIR
location ('emp.dmp')
) as select emp_id, emp_name, dept_id from emp order by dept_id
/
Copy file then, import in dest database:
create table import_emp_info
(EMP_ID NUMBER(12),
EMP_NAME VARCHAR2(100),
DEPT_ID NUMBER)
organization external
( type oracle_datapump
default directory DATA_PUMP_DIR
location ('emp.dmp')
)
/
insert into emp_info select * from import_emp_info;
如果您不希望或不能在源数据库上拥有外部表,则可以使用emp表的直接expdp(如果您对源数据库目录的访问权限有限,则可能使用NETWORK_LINK结构)和QUERY进行排序。
答案 3 :(得分:0)
您可以将数据从源表A加载到中间表B,然后在B和目标表C之间进行分区交换。精确复制,不涉及排序。
答案 4 :(得分:0)
这种I / U / D复制形式是MERGE命令的用途。非常值得怀疑的是,需要进行昂贵的排序合并,而且我希望看到散列连接。只要哈希表可以存储在内存中,哈希连接就比扫描表格要贵得多。
一个方便的优化是根据非键属性存储哈希值,这样您就可以在键列上的源表和目标表之间进行连接,并比较小哈希值而不是整列列 - 变化检测变得容易。