2013-10-22 76 views
1

请原谅我的英语。 我有两个表,都是按日期间隔分区,但在不同的领域。 两个表中都有大量的记录(每个分区〜100kk)。 第一张表在快速分区表空间中保留最后3个(按日期)分区,其他分区分配在慢速分区表空间中。 另外我有一些系统,处理数据。它并行执行进程,每个通过select语句从第一个表中获取数据,并将处理后的数据放入第二个表中。 所以我需要从第一个表中选择数据只从“快速”(!)分区放到第二个表中。 但第二个表在其他(日期太)字段分区。当进程并行执行时,当不同的进程试图将数据放入第二个表中的同一分区时,会发生死锁。一次从多个分区中选择

好的解决方案是,每个进程仅从第2个表中的“快速”分区(但所有这些分区都在一次)获取数据。在这种情况下,每个进程将在一个分区中推送数据。但我不知道如何去做。

如果我让

select t.field1, t.field2 from (select * from FIRST_TABLE partition("P1") union all 
select * from FIRST_TABLE partition("P2") union all 
select * from FIRST_TABLE partition("P3")) t 
where t.field3='someVal' --Indexed field in FIRST_TABLE 

将OracleDB的使用本地索引分区上的FIRST_TABLE解决where子句?这种方式将如何影响性能?

任何想法来解决我的问题?

PS关于如何从一个select语句中的多个分区中选择数据有很多问题,但我没有找到适合我的情况的答案。

+0

可能的重复[如何做一个SQL选择多个分区?](http://stackoverflow.com/questions/4268139/how-does-one-do-a-sql-select-over-multiple-分区) – javaPlease42

回答

3

查询分区表时,几乎不希望使用PARTITION子句。您几乎总是希望指定一个谓词,允许Oracle自行进行分区修剪。

SELECT t.column1, t.column2 
    FROM first_table t 
WHERE t.partitioned_date_column >= <<date that delimits fast partitions>> 
    AND t.column3 = 'someVal' 

当指定在该表已分区上,Oracle可以自动确定哪个分区(多个)日期列谓词需要访问。

+0

+1打我吧;) – tbone

+0

如果我需要将旧分区中的一个移动到快速表空间并重新处理数据(对不起,我没有写关于这个限制的问题)?这种方式不允许定义分离的分区?没有一个接一个地铺设。 – Andrey

+0

@Andrey--我不确定这是怎么改变的。你仍然想在'partitioned_date_column'上指定一个谓词来指定哪些分区需要读取。如果您说日期范围可能不连续,那么您可能需要一些谓词“OR”,而不是“> =”,否则您可能需要一个“IN”列表。 –

0

你可以得到的僵局,如果你想在自己的并行执行三个查询,例如在同一时间运行:

insert into t2 select from t1 partition ("P1"); 

,然后在另一个shell /窗/工作:

insert into t2 select from t1 partition ("P2") 

如果查询

select * 
from t1 
where date_column_used_for_partition >= 3_dates_ago 

甲骨文将只选择您需要的三个分区你不需要使用UNION

通过这种方式,您可以将您的INSERT INTO... SELECT语句放在一个查询中,而且您不必担心死锁,Oracle引擎会知道第二个表的哪个分区必须插入数据,他将管理为您插入。