一次从多个分区中选择

时间:2013-10-22 16:12:29

标签: sql oracle database-partitioning

对不起我的英语。 我有2个表,都按日期间隔分区,但在不同的字段上。 两个表中都有大量记录(每个分区约100kk)。 第一个表在快速discks表空间中保留它的最后3个(按日期)分区,其他分区在缓慢的discks表空间中。 我还有一些处理数据的系统。它并行执行进程,每个进程通过select语句从第一个表获取数据,并将处理后的数据放入第二个表。 所以我需要从“快速”(!)分区中的第一个表中选择数据以将其放入第二个表中。 但是第二个表在其他(date date)字段上分区。当进程并行执行时,当不同的进程试图将数据放入第二个表中的同一个分区时,我会遇到死锁。

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

如果我做

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语句中从多个分区中选择数据有很多问题,但我没有找到对我的情况有用的答案。

2 个答案:

答案 0 :(得分:4)

在查询分区表时,您几乎不想使用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可以自动确定需要访问哪些分区。

答案 1 :(得分:0)

如果您尝试自己并行执行三个查询(例如同时运行),则可能会出现死锁:

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

然后在另一个shell / window / job中:

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

如果您查询

select *
from t1
where date_column_used_for_partition >= 3_dates_ago

Oracle将只选择您需要的三个分区,您不需要使用UNION

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