インデックスが利用されたかどうかを明示する options msglevel=i

例えば、以下のコードで3000000obsのデータセットを作り
全く同じ内容の変数ZとZ2を作成しZの方にだけインデックスをつけます。

data Q1(index=(Z));
 do X=1 to 1000000;
  do Y='A','B','C';
   Z=cats(put(X,best.),Y);
   Z2=cats(put(X,best.),Y);
    output;
  end;
 end;
run;

まずインデックスを参照せずに抽出をしてみます。
data A1;
 set Q1;
 where Z2='10B';
run;









となりました。環境によって処理時間はかわりますので参考まで

処理時間10.38 
CPU時間1.48

で次にインデックスが掛った変数で抽出します

data A1;
 set Q1;
 where Z='10B';
run;








処理時間0.03
CPU時間0.01

となります。

歴然と速くなっています。

これは、インデックスを参照して抽出をしているからです。


ただ、まあ、速くなったのはわかるんですが、、、
なんか、インデックスが使われたかどうか何もわからないと
どうもモチベーションがあがりません。

あ、ちなみにSASは、データセットの色々な要素から、インデックスを使った方が速くなる
と判断すれば利用し、いや、かえって全部順番に読んだ方が速いと判断したら
インデックスがついていても使いません。
だいたいこういう時につかわれるといったセオリーはあるのですが基本的にはブラックボックス
SASの心の赴くままにです。

せっかく親切にインデックスつけたのに、それじゃあ、つれないですよね。

なのでここで久々の

options msglevel=i;

です。

これをつけるとログが、やたら細かい情報も教えてくれるようになり、
マージで変数の上書きに注意するときなどに重宝すると紹介したものです。

で、これをかけてから

同じように実行すると


となって、INFOで、ちゃんと教えてくれます。
色をつけたい方は拡張エディタの設定をいじってください。

さて、今後はどういった処理だとインデックスが有効かを説明します。

実はwhere文の書き方によって、結果は同じ意味でも
インデックスを絶対使ってくれない損な書き方があります。
それを知っていないと、せっかくインデックス作っても無駄骨です。

また、今回は抽出の処理時間をみて
インデックスすげーといった紹介をしましたが、
何事にも裏の面があります。

実はデータセットが巨大になればなるほど、インデックスを付与することに
パワーが必要になって、作成に時間がかかったりして、トータルで考えると速くなっていない
ケースもありえます。
その辺りのトレードオフは、常にケースバイケースなので慣れが必要だと思います。

巨大なデータセットに対して、後で何度も、抽出等の処理をかけなければならない場合は
作成時に付与しておくと、以降の処理で節約できた時間の合計が、作成に余計にかかる時間を
こえて、やったねとなったります。

例えば医薬系でいうと、MedDRAや薬剤コード辞書などを永久データセットにする際にインデックスをつけておけば後に、CRFデータとそれらをマッチングしたり、検索をかけたりする際にとても
役立ちます。










0 件のコメント:

コメントを投稿