2014-10-28 109 views
0

我有2個數據集:t.a有390K行和1個變量,t.b有6000萬行和350個變量。 我需要快速加入這些數據集,但我的查詢太慢了。如何優化SAS中的proc sql join?

如何優化查詢?

我的查詢:

proc sql; 
    create table с as 
    select distinct a.REP_CLID, b.REP_DATE, &Score_Column, b.REP_AGE as AGE 
    from a (IDXWHERE =Yes) , 
    &b (IDXWHERE =Yes) 
    where a.rep_clid = b.rep_clid 
+0

在你的數據庫中,你有IDXWHERE上的索引嗎?尤其是b表。 – Mihai 2014-10-28 08:54:57

+0

是的,我有。使用索引查詢大約42分鐘,沒有他們 - 51分鐘。 – user3306125 2014-10-28 09:00:55

+0

我猜rep_clid是主鍵,你真的需要清楚嗎? – Mihai 2014-10-28 09:04:06

回答

1

既然你已經在你的大表B對rep_clid索引,這似乎是一個很好的候選人數據步鍵合併。調整爲感興趣的需要所以你只是保持變量:

data c; 
    set a; 
    set b key = rep_clid; /*requires unique index on rep_clid to work properly*/ 
    if _IORC_ then do; 
    _ERROR_ = 0; 
    delete; 
    end; 
run; 

將與rep_clid出現在A和B僅返回的記錄。然後,您可以使用nodupkey選項通過proc進行重複數據刪除。

如果您有關於B A非唯一索引,它仍可以工作,但語法是有點複雜:

data c; 
    set a; 
    do until(eof); 
    set b key = rep_clid end = eof; /*will work with non-unique index on rep_clid*/ 
    if _IORC_ then do; 
     _ERROR_ = 0; 
     delete; 
    end; 
    else output; 
    end; 
run; 
0

性能可以是一個棘手的問題,因爲有一個龐大的數字可能影響它的因素。在找到性能最好的方法之前,通常會嘗試多種方法來實現相同的目標。

這些表是SAS表還是一個或兩個第三方DBMS表?這打開了整個世界的性能問題,我將離開,直到確認。

假設他們都是SAS表,如果你只想從表B中獲得列,假設他們都是SAS表,假設& Score_Column在表B中。如果不是,那麼這將不起作用。

proc sql; 
    create table с as 
    select distinct b.REP_CLID, b.REP_DATE, &Score_Column, b.REP_AGE as AGE 
    from &b (IDXWHERE =Yes) as  b 
    where b.rep_clid in 
      ( select a.rep_clid 
       from a (IDXWHERE =Yes) 
      ) 
    ; 
Quit; 

或者,您可以使用proc格式,如建議。如果& Score_Column在表格a中,但是如果不是,則可以很容易地修改該示例。

Proc sql; 
     create table rep_clid_fmt as 
     select distinct  'rep_clid_fmt' as fmtname 
     ,  rep_clid      as  start 

/*    If &Score_Column is in table a then use &Score_Column as the label */ 
     ,  &Score_Column     as  label 

       else use a flag like... 
     ,  'keep'       as  label 

     from a 
     ; 
Quit; 

Proc format cntlin=rep_clid_fmt; 
Run; 


proc sql; 
    create table с as 
    select distinct b.REP_CLID 
     , b.REP_DATE 
     , put (b.REP_DATE,rep_clid_fmt) as  &Score_Column 
     , b.REP_AGE as AGE 
    from &b (IDXWHERE =Yes) as  b 
    where put (b.REP_DATE,rep_clid_fmt)  ne substr (b.REP_DATE,1,length(put(b.REP_DATE,rep_clid_fmt)) 
    ; 
Quit; 

祝你好運!