PROC SQLに 昔からあるオプション、機能だが使うのは初めて _METHOD _TREEを試しました。処理時間に問題ありということで、PROC SQL _METHOD _TREE; という具合にオプションを足すと、クエリを評価する順序や評価のツリー構造をログに出力してくれます。
これ DATAステップでインデクス作ったのに使っていないとかログを見ると判ります。性能調整のヒントに FULLSTIMERと一緒に合わせて使えます。
SASプログラムとログを解析するユーティリティを開発するための備忘録です。This is a memo to develop utility that analyzes the SAS log.
PROC SQLに 昔からあるオプション、機能だが使うのは初めて _METHOD _TREEを試しました。処理時間に問題ありということで、PROC SQL _METHOD _TREE; という具合にオプションを足すと、クエリを評価する順序や評価のツリー構造をログに出力してくれます。
これ DATAステップでインデクス作ったのに使っていないとかログを見ると判ります。性能調整のヒントに FULLSTIMERと一緒に合わせて使えます。
マクロを書いていて地味に困るのがテンポラリのファイル参照名、ライブラリ参照名を定義することです。ユニークでぶつからない名前を定義するために、小さいコードを書きました。参照するファイルが、SASファイルでも動くようにアンダースコアで始まるようにしています。filename関数でテンポラリの名前を作ると #LN00058 のような名前になります。これだと正しくアサインできないときがあるので、アンダースコア始まりにしています。
それと、マクロの定義を削除するステートメントを良く忘れるのでメモしておきます。%SYSMACDELETE で定義したマクロを削除します。AUTOEXECの中で使うけど最後には後始末しておきたいときに使います。
%macro _uname(); %local n; %let n=%sysfunc(monotonic()); _LN%sysfunc(putn(&n, z5.)) %mend; %put %_uname;
CPORTで移送ファイルを作成するときに圧縮できることを実験で確認した。移送ファイル形式は圧縮されてはいるが圧縮率は高くない。なので、FILENAMEステートメントでZIPの圧縮を試してみた。圧縮した移送ファイルからCIMPORTできて /tmp/new のディレクトリにもSASファイルがあることを確認できた。。
filename myfile1 '/tmp/foo.xpt'; proc cport lib=sashelp file=myfile1 memtype=data; select air baseball class; run; filename myfile2 zip "/tmp/foo.xpt.zip"; proc cport lib=sashelp file=myfile2 memtype=data; select air baseball class; run; libname newlib '/tmp/new'; proc cimport lib=newlib infile=myfile2; run;
リッチな本番環境だと問題が起きるが、開発環境だと問題が起きにくいというのはよくある。本番のデータは大きいが開発環境はダミーで小さなものしかない。そんなときは、メモリとかのパラメータをわざと低くしたりすると再現しやすくなる。メモリが不足していると辺りが付いていたら使える手です。
追記: タイムアウト系のエラーは、起動のスクリプトに sleep を入れることで再現させることができます。例えば、Workspace Serverの起動のタイムアウトは *_usermods.sh にシェルのコマンド sleep 120; とか入れると再現できます。
負荷が高いというのは Linuxであれば stress(1) とかで疑似的な負荷を掛ける手もあります。負荷掛けると狙っているのとは別なエラーも出るので見極め必要です。
クエリパラーメータを渡すときにエンコーディングが面倒だと思っていたら、PROC HTTPのQUERYのオプションで自動的にエンコードしてくれることに気が付いた。REST APIで日本語の名前でフィルタするときに使える。
%let name=%str(負荷テスト); proc http url="https://%sysget(SAS_JOB_FLOW_SCHEDULING_SERVICE_HOST):443/jobFlowScheduling/flows" query=("filter"="eq(name,'&name')") out=outjson oauth_bearer=sas_services; headers 'Accept'='application/vnd.sas.collection+json'; run;
SAS/ACCESSのデータベースを乗り換えたときに、WHERE句の関数がプッシュダウンされているか知りたいという問合せがあった。DBの種類にもよるかもしれないが、OBS=1 を指定すると SQLにLMIT=1が効く場合がある。これでSASログを確認してプッシュダウンされない部分を特定していく。
options sastrace=',,t,d' sastraceloc=saslog stsuffix obs=1; proc sql; create table x as select * from hoge.xyz; quit; options sastrace=off obs=max;
SAS Viya CLIの入門として資料を書き起こしました。CLIを使ってViyaのシステムを管理したい人向けです。内容を以下に示します。
title "!SASROOT/sashelp/class.sas7bdat"; proc compare base="!SASROOT/sashelp/class.sas7bdat"(drop=age) compare="!SASROOT/sashelp/class.sas7bdat"; run; title;
$ export ACCESS_TOKEN=$(cat ~/.sas/credentials.json | jq -r '.Default."access-token"') $ export URL=https://viya4.example.com/jobExecution/jobs $ curl -k "${URL}?limit=1000&filter=and(ge(creationTimeStamp,2022-04-07),ne(state,"completed"))&orderby=endTimeStamp" -H "Authorization: Bearer $ACCESS_TOKEN" | jq -r '.items[] | [.state, .id, .jobRequest.name, .endTimeStamp, .creationTimeStamp, .modifiedTimeStamp, .elapsedTime, .createdBy, .modifiedBy, .error.message, .error.errorCode ]'
SASでREST APIを使うときにアンパサンドのエスケープでしばし悩んだのメモしておきます。URLの後ろにクエリパラメータを書くときに必要になります。&はマクロ変数を展開するときの目印であるので、これが展開されないように工夫します。で、いろいろ試したのですが1回で代入ではなく、2回の代入と関数の組み合わせで動きました。1回の代入でとも思いますが、通常URLはベースの部分とパラメータの部分に分かれるので、変数を分けた方が可読性が良いです。
追記: クエリのパラメータは PROC HTTPのオプションの機能を使う方がスマートだと判りました。以下の記事を参照してください。
http://sasutility.blogspot.com/2022/10/proc-http.html