[英]Optimal way to transfer 4 Virtual SDA Tables in Hana DB
問題:我的團隊目前正在進行從 ECC 系統到新 S/4 Hana 系統的 ERP 遷移。 作為上線的一部分,我們的團隊需要將所有表從 S/4 系統復制到我們將托管數據的 SLT 模式中。 大多數表將由 SAP 之外的 SLT 復制處理。 但是,由於時間緊迫,我們確定了 4 個需要多天復制的表。 想法是從遠程源 (ABAP/SDA) 復制現有數據並放置在我們的 SLT 模式中。 一旦完成,我們可以激活點前向復制並允許更新所有新的或修改的記錄查看 SLT 復制。
嘗試的方法:我們當前的方法是與后端 S/4 數據庫建立 SDA 連接,並按年份分解數據,以使用存儲過程插入到我們的本地表中。 這種方法出現了許多問題,但它目前正在發揮作用。 它只是超級慢。
論壇問題:
示例:假設我們有一個名為: A_tbl的源表
然后我們將有我們的目標表: B_tbl
當前程序:
CREATE OR REPLACE procedure LOAD_B_TBL_FROM_A_TBL ()
as
begin
declare v_offset_nbr integer;
declare v_record_count integer;
declare v_commit_count integer;
declare i integer;
declare v_year nvarchar(4);
declare v_record_per_commit_count CONSTANT INT = 1000000;
declare v_table_name CONSTANT NVARCHAR(30) = 'A_TBL';
declare v_start_year CONSTANT INT = 2011;
declare v_end_year CONSTANT INT = 2022;
declare year_nbr integer;
for year_nbr in v_start_year..v_end_year do
select IfNull(max(offset_nbr),0) into v_offset_nbr from B_TBL_SCHEMA.bulk_load_log where table_name = :v_table_name AND year_nbr = to_varchar(year_nbr); -- Get offset number of records
select count(*) into v_record_count from A_TBL_SCHEMAA_TBL A_TBL WHERE A_TBL.YEAR = to_varchar(year_nbr); -- Count the source records.
v_record_count = v_record_count - v_offset_nbr; -- Subtract out the records already committed for the current year. Failsafe if procedure fails
v_commit_count = v_record_count / v_record_per_commit_count; -- Number of times we need to loop
IF v_record_count < v_record_per_commit_count THEN -- Don't enter the loop if it's not necessary
INSERT INTO B_TBL_SCHEMA.B_TBL (
SELECT * FROM A_TBL_SCHEMAA_TBL
WHERE A_TBL.YEAR = to_varchar(year_nbr)
); -- Insert into our target table
COMMIT;
insert into B_TBL_SCHEMA.bulk_load_log values(
v_table_name,
to_varchar(year_nbr),
:v_offset_nbr,
now()
); -- Insert into a logging table to keep up with offset
ELSE
for i in 0..v_commit_count do -- Loop number of commit times. (500 million / 1 million) = 500 commits necessary to process entire table
INSERT INTO B_TBL_SCHEMA.B_TBL (
SELECT * FROM A_TBL_SCHEMAA_TBL
WHERE A_TBL.YEAR = to_varchar(year_nbr)
LIMIT :v_record_per_commit_count OFFSET :v_offset_nbr
); -- Insert into our target table
COMMIT;
v_offset_nbr = v_offset_nbr + v_record_per_commit_count; -- Update the offset before logging so we know where to begin if procedure fails
insert into B_TBL_SCHEMA.bulk_load_log values(
v_table_name,
to_varchar(year_nbr),
:v_offset_nbr,
now()
); -- Insert into logging table to keep up with offset
COMMIT;
end for;
end if;
end for;
end;
我認為在沒有任何額外管理的情況下傳輸表的最簡單和最快的方法是使用BINARY
格式選項的EXPORT
語句。 這也可以通過架構上的 HANA 工作室上下文菜單或通過File -> Export... -> SAP HANA -> Catalog Objects
、 File -> Import...
來完成。
使用這種方法,您可以手動設置導出和導入的線程數,而無需額外的棘手代碼。 在目標系統中導入后,您將擁有與源系統中相同架構中具有相同結構的相同表,因此要將表移動到新名稱或架構,您需要先將其復制到源中。 導入后,您可以在目標表中insert... select...
或在源系統中創建具有所需分區的副本表或在目標中重新分區導入的表並將其用作目標表。
有什么優點:
最后,我通過 HANA studio(導入到本地機器)在我的系統中對此進行了測試:具有 130M 記錄和 57 列的 5Gb 大小的表在 6 分鍾內以 8 個線程導出。
您的原始方法如何:您應該始終禁用真正批量操作的刪除索引和約束,並在最后重建/啟用它們,以節省插入期間索引重建或約束檢查的時間。
性能瓶頸可能是僅使用一個線程的 SDA 傳輸。
一種解決方法可能是:
這是一些偽代碼。
-- virtual table to source A over SDA: VT_TBL_A
-- target table B: TBL_B
CREATE OR REPLACE FUNCTION F_TBL_A_YEAR ( IN YEAR INT)
RETURNS TABLE ( ... )
as begin
select * from VT_TBL_A where year(MY_DT_COLUMN) = :YEAR;
end;
DO
BEGIN
DECLARE t_var LIKE TBL_B;
--list of all 'partitions'
years=select distinct year(MY_DT_COLUMN) as MY_YEAR from VT_TBL_A;
--call the function for each year
t_var = MAP_MERGE(:years, F_TBL_A_YEAR( :years.MY_YEAR));
insert into TBL_B select * from :t_var;
commit;
END;
在此運行時,我建議您檢查系統視圖 M_REMOTE_STATEMENTS 以確認記錄是通過多個連接傳輸的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.