2017-04-13 98 views
0

現在我面臨着一個優化問題。 我有一個列表(17000+),其中一些不活躍。該列表由客戶端提供給EXCEL文件,他要求我重新發送它們(明顯只有那些活動的)。SQL優化

爲此,我必須根據客戶提供的清單過濾生產數據庫。不幸的是,我無法將列表加載到生產的一張表中,然後加入主文章表中,但是我可以將其轉換爲UAT數據庫,並與生產數據庫鏈接。

生產商品主數據包含200個000 000多個行,但將其過濾,我可以redure至約80 000 000

我命令中檢索只從生產活性製品,想到使用集合但它似乎最後一個過濾器太長了。

這裏是我的代碼:

declare 
    type t_art is table of number index by pls_integer; 
    v_art t_art; 
    v_filtered t_art; 
    idx number := 0; 
begin 
    for i in (select * from [email protected]_DATABASE) 
    loop 
    idx := idx + 1; 
     v_art(idx) := i.art_nr; 
    end loop; 

    for j in v_art.first .. v_art.last 
    loop 
     select distinct art_nr 
     bulk collect into v_filtered 
     from production_article_master_data 
     where status = 0 -- status is active 
     and sperr_stat in (0, 2) 
     and trunc(valid_until) >= trunc(sysdate) 
     and art_nr = v_art(j); 
    end loop; 
end; 

說明:從UAT數據庫,通過DBLINK,我insertinting列表到生產(v_art)關聯數組。然後,對於v_art中的每個值(17000+ distinct articles),我將使用生產文章主數據進行過濾,並在第二個ASSOCITIAVE ARRAY中返回僅有效文章(可能爲6-8000)。

不幸的是,這種過濾操作需要數小時。 有人可以提供一些提示,如何改進這orde減少執行時間,請?

謝謝

+0

使用集合在一個循環像這樣做將不起作用,因爲每次迭代調用'BULK COLLECT INTO'時,'v_filtered'集合將被重新初始化爲一個新的(空)集合。 – MT0

回答

2

只需使用SQL和連接兩個表:

select distinct p.art_nr 
from production_article_master_data p 
     INNER JOIN 
     [email protected]_DATABASE t 
     ON (p.art_nr = t.art_nr) 
where status = 0 -- status is active 
and sperr_stat in (0, 2) 
and trunc(valid_until) >= trunc(sysdate) 

如果你必須這樣做,在PL/SQL,則:

CREATE OR REPLACE TYPE numberlist IS TABLE OF NUMBER; 
/

declare 
    -- If you are using Oracle 12c you should be able to declare the 
    -- type in the PL/SQL block. In earlier versions you will need to 
    -- declare it in the SQL scope instead. 

    -- TYPE numberlist IS TABLE OF NUMBER; 

    v_art  NUMBERLIST; 
    v_filtered NUMBERLIST; 
begin 
    select art_nr 
    BULK COLLECT INTO v_art 
    from [email protected]_DATABASE; 

    select distinct art_nr 
    bulk collect into v_filtered 
    from production_article_master_data 
    where status = 0 -- status is active 
    and sperr_stat in (0, 2) 
    and trunc(valid_until) >= trunc(sysdate) 
    and art_nr MEMBER OF v_art; 
end; 
+0

你確定通過DBLink連接2個表是最好的解決方案(考慮到第一個表非常大)?! – mikcutu

+0

@mikcutu我還添加了一個不依賴循環的PL/SQL版本。我無法告訴你什麼會更高性能,因爲我無法訪問數據庫和網絡 - 所以您需要嘗試各種選項並查看。 – MT0

+0

數據庫版本是11.1.0.7.0
我不允許在生產數據庫上創建對象
...但似乎通過DBLink的選擇在時間上成功完成。 – mikcutu