我有一个巨大的表格。第一个范围按price_date进行分区,然后用fund_id对哈希进行分区。该表有4.3亿行。我每天都有一份批量工作,每天插入150万到300万行。将数据加载到巨大的分区表
我们正在寻找的用于启用和禁用本地索引(并非所有的指标,但在此基础上分区由唯一的数据感动数据)
没有人有在做插入大表的运行速度没有下降,重建经验技术?
有没有人只对这种情况有任何建议?
我有一个巨大的表格。第一个范围按price_date进行分区,然后用fund_id对哈希进行分区。该表有4.3亿行。我每天都有一份批量工作,每天插入150万到300万行。将数据加载到巨大的分区表
我们正在寻找的用于启用和禁用本地索引(并非所有的指标,但在此基础上分区由唯一的数据感动数据)
没有人有在做插入大表的运行速度没有下降,重建经验技术?
有没有人只对这种情况有任何建议?
去阅读这样的:
http://www.evdbt.com/TGorman%20TD2005%20DWScale.doc
这工作。
您是否面临在线查询或迟到数据(例如,您今天/昨天的任何一天今天能排到哪一行)的挑战?
我已经得到了扫描我要加载的记录的数据集的代码,并且在表子分区将要被修改时标记本地索引子分区。 (我使用这个而不是Tim Gorman的参考文献,因为我有迟到的数据,需要同时向最终用户提供临时区域和仓库本身。)
我的表是范围/列表,而不是范围/散列。所以你将不得不修改它,可能使用ORA_HASH函数来找到正确的子分区。我还写了一张表,我将标记为不可用的子分区,所以我可以一次完成所有这些。在单个ALTER TABLE语句中将所有子分区的索引标记为不可用可能会稍微高效一些;我最初只禁用BITMAP索引,但即使在数据加载过程中使单个B *树索引脱机,也可以显着提高效率。
procedure DISABLE_LOCAL_INDEXES as
l_part_name varchar2(30);
l_subpart_name varchar2(30);
l_sql varchar2(2000);
type partition_rec_type is record
(table_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
list_value varchar2(10),
min_ts timestamp,
max_ts timestamp);
type partition_recs_type
is table of partition_rec_type;
l_partition_recs partition_recs_type := partition_recs_type();
l_partition_rec partition_rec_type;
l_subpart_id number := 1;
l_start_ts timestamp;
l_end_ts timestamp;
l_found_list_part boolean;
begin
-- build set of subpartitions
l_start_ts := to_timestamp ('1970-01-01', 'yyyy-mm-dd');
for i in (select p.table_name, p.partition_name, sp.subpartition_name,
p.high_value as part_high_value,
sp.high_value as subpart_high_value,
p.partition_position, sp.subpartition_position
from user_tab_subpartitions sp
inner join user_tab_partitions p
on p.table_name = sp.table_name
and p.partition_name = sp.partition_name
where p.table_name = 'MY_TARGET_TABLE'
order by p.partition_position, sp.subpartition_position)
loop
if ((i.partition_position <> 1) and (i.subpartition_position = 1)) then
l_start_ts := l_end_ts + to_dsinterval('0 00:00:00.000000001');
end if;
if (i.subpartition_position = 1) then
l_end_ts := high_val_to_ts (i.part_high_value);
l_end_ts := l_end_ts - to_dsinterval('0 00:00:00.000000001');
end if;
l_partition_rec.table_name := i.table_name;
l_partition_rec.partition_name := i.partition_name;
l_partition_rec.subpartition_name := i.subpartition_name;
l_partition_rec.list_value := i.subpart_high_value;
l_partition_rec.min_ts := l_start_ts;
l_partition_rec.max_ts := l_end_ts;
l_partition_recs.extend();
l_partition_recs(l_subpart_id) := l_partition_rec;
l_subpart_id := l_subpart_id + 1;
end loop;
-- for every combination of list column and date column
-- which is going to be pushed to MY_TARGET_TABLE
-- find the subpartition
-- otherwise find the partition and default subpartition
for i in (select distinct LIST_COLUMN, DATE_COLUMN as DATE_VALUE
from MY_SOURCE_TABLE
where IT_IS_BEING_MOVED_TO_TARGET IS TRUE)
loop
-- iterate over the partitions
l_found_list_part := false;
for k in l_partition_recs.first..l_partition_recs.last
loop
-- find the right partition/subpartition for list_value/date_value
if ( (i.DATE_VALUE >= l_partition_recs(k).min_ts)
and (i.DATE_VALUE <= l_partition_recs(k).max_ts)) then
if (l_found_list_value = false) then
if (to_char(i.LIST_COLUMN, '9999') = l_partition_recs(k).LIST_COLUMN) then
l_found_list_value := true;
elsif (l_partition_recs(k).LIST_COLUMN = 'DEFAULT') then
l_partition_rec := l_partition_recs(k);
end if;
end if;
end if;
end loop; -- over l_partition_recs
-- log those partitions for later index rebuild
begin
insert into index_subpart_rebuild
(table_name, partition_name, subpartition_name)
values
(l_partition_rec.table_name, l_partition_rec.partition_name,
l_partition_rec.subpartition_name);
exception
when dup_val_on_index then null;
when others then raise;
end;
end loop; -- over MY_TARGET_TABLE.DATE_VALUE values
commit;
for i in (select ui.index_name, uis.subpartition_name
from user_indexes ui
inner join user_ind_subpartitions uis
on ui.index_name = uis.index_name
inner join index_subpart_rebuild re
on re.subpartition_name = uis.subpartition_name
where ui.table_name = 'MY_TARGET_TABLE')
loop
l_sql := 'alter index ' || i.index_name ||
' modify subpartition ' || i.subpartition_name || ' unusable';
execute immediate l_sql;
end loop;
end DISABLE_LOCAL_INDEXES;
+1。 (不能说这是否解决@ sumanta的问题。) – 2010-08-24 20:11:48
我不知道你正在使用的数据库,
在SQL SERVER的情况下,尝试创建一个临时表,将数据装入该表,这个临时表建立索引和约束上,并使用
带SWITCH子句的ALTER TABLE将此作为新分区添加到当前表中。
你每天都在加载一个新的分区吗?可能不会。你正在加载到一个现有的分区吗?几个不同的分区?大部分现有分区? – APC 2010-08-24 11:43:19
APC的问题除外:所有索引都是本地的吗? – dpbradley 2010-08-24 14:06:54