2014-10-28 4 views
0

У меня есть 2 набора данных: t.a с 390K строк и 1 переменная и t.b с 60 миллионами строк и 350 переменных. Мне нужно быстро присоединиться к этим наборам данных, но мой запрос слишком медленный.Как оптимизировать proc sql join в SAS?

Как я могу оптимизировать запрос?

Мой запрос:

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? Особенно в таблице. – Mihai

+0

Да, у меня есть. С запросами индексов работает около 42 минут, без них - 51 мин. – user3306125

+0

Я предполагаю, что rep_clid - это первичный ключ, вам действительно нужен отдельный? – Mihai

ответ

1

Поскольку у вас уже есть индекс по rep_clid в вашей большом столе б, это кажется хорошим кандидатом для слияния ключевого шага данных. Tweak, как это требуется, так что вы просто держать переменные, представляющие интерес:

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 в настоящее время как а и Ь. Затем вы можете дедуплицировать через сортировку proc с помощью опции nodupkey.

Если у вас есть не уникальный индекс б, он все еще может быть сделано для работы, но синтаксис немного сложнее:

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 или одна или обе таблицы сторонних СУБД? Это открывает целый мир проблем с производительностью, которые я оставлю до тех пор, пока не будет подтверждено.

Предполагая, что они обе таблицы 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; 

Удачи вам!