簡體   English   中英

如何在SAS中優化proc sql join?

[英]How to optimize proc sql join in SAS?

我有2個數據集:ta有390K行和1個變量,而tb有6000萬行和350個變量。 我需要快速加入此數據集,但查詢速度太慢。

如何優化查詢?

我的查詢:

    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 

由於您已經在大型表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;

那將只返回a和b中都存在rep_clid的記錄。 然后,您可以使用nodupkey選項通過proc sort進行重復數據刪除。

如果您在b上具有非唯一索引,則仍然可以使它工作,但是語法稍微復雜一些:

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;

性能可能是一個棘手的問題,因為會影響性能的因素很多。 在找到最佳方法之前,通常嘗試多種方法來實現同一目標。

這兩個表都是SAS表還是一個或兩個第三方DBMS表? 這將打開一個性能問題的世界,我將在確認之前將其保留。

假設它們都是SAS表,並且如果只希望表B中的列,則嘗試以這種方式重新編寫查詢,並假設&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; 

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM