Использует ли когда-либо SAS Proc SQL индекс при объединении - PullRequest
2 голосов
/ 12 октября 2009

Рассмотрим следующий (по общему признанию длинный) пример.

Пример кода создает два набора данных: данные один с «ключевыми» переменными i, j, k и данные два с ключевыми переменными j, k и переменной «значение» x. Я хотел бы объединить эти два набора данных максимально эффективно. Оба набора данных индексируются относительно j и k: индекс для первых данных не должен быть нужен, но он все равно есть.

Proc SQL не использует индекс в данных два, что, я полагаю, имело бы место, если бы данные были в реляционной базе данных. Это просто ограничение оптимизатора запросов, которое я должен принять?

РЕДАКТИРОВАТЬ: Ответ на этот вопрос - да, SAS может использовать индекс для оптимизации соединения PROC SQL. В следующем примере значения относительных размеров наборов данных имеют значение: если вы измените код так, чтобы данные два стали относительно большими, чем данные один, будет использоваться индекс. Неважно, отсортированы ли эти наборы данных.

* Just to control the size of the data;
%let j_max=10000;

* Create data sets;
data one;
    do i=1 to 3;
        do j=1 to &j_max;
            do k=1 to 4;
                if ranuni(0)<0.9 then output;
            end;
        end;
    end;
run;

data two;
    do j=1 to &j_max;
        do k=1 to 4;
            x=ranuni(0);
            if ranuni(0)<0.9 then output;
        end;
    end;
run;

* Create indices;
proc datasets library=work nolist;
    modify one;
    index create idx_j_k=(j k);
    modify two;
    index create idx_j_k=(j k) / unique;
run;quit;

* Test the use of an index for the other data set:
* Log should display "INFO: Index idx_j_k selected for WHERE clause optimization.";
options msglevel=i;
data _null_;
    set two(where=(j<100));
run;

* Merge the data sets with proc sql - no index is used;
proc sql;
    create table onetwo as
    select
        one.*,
        two.x
    from one, two
    where
        one.j=two.j and
        one.k=two.k;
quit;

1 Ответ

6 голосов
/ 12 октября 2009

Вы можете сравнивать яблоки и апельсины. Для объединения, которое вы делаете с proc sql, индекс может не помочь, потому что наблюдения уже упорядочены по j и k, и существуют более быстрые способы «объединения», чем использование индексов.

Для поднабора, который вы выполняете с шагом data _null_, с другой стороны, индекс на j наверняка поможет. Если вы сделаете то же подмножество с proc sql, вы увидите, что оно равно с использованием индекса.

proc sql;
  select * from two where j < 100;
quit;
/* on log
INFO: Index idx_j_k selected for WHERE clause optimization.
*/

Кстати, вы можете использовать недокументированную опцию _method, чтобы проверить, как proc sql выполняет ваш запрос. На моем sas 9.2 на windows он сообщает, что делает то, что называется «хеш-соединением»:

proc sql _method;
  create table onetwo as
  select
    one.*,
    two.x
  from one, two
  where
    one.j=two.j and
    one.k=two.k;
quit;

/* on log
NOTE: SQL execution methods chosen are:

  sqxcrta
      sqxjhsh
          sqxsrc( WORK.ONE )
          sqxsrc( WORK.TWO )
*/

См. Техническую записку Пола Кента для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...