【ABAP】S/4HANAへの移行でSELECT SINGLEの取得結果がズレてしまう理由

ECCでは問題なく動いていたSELECT SINGLEがS/4HANAへの移行後に「別のレコードを拾うようになってしまった」という問題に遭遇したことはないでしょうか?

この手の話はかなりの頻度で起きている現象です。勘違いされやすいのが、「S/4 HANAになったことでSELECT SINGLEの使用が変わった」という解釈です。

実際のところは「もともとどの1件を拾うか未定義だったコードが、HANAデータベースの実行のされ方により、未定義が表面化しただけ」です。

この記事では、S/4HANAへの移行でずれが出るメカニズムをHANAデータベースが列型(column-oriented)であることを絡めて解説していきます。

目次

ORDER BYなしの結果順は未定義扱い

まず押さえるべき点として、ABAP Open SQLでも通常のSQLでもSELECT SINGLE命令は、実質的に「条件に合う行が複数ある中で、どれか1行を運任せに拾う」命令になります。ECCでいつも同じ行が返ってきていたとしても、それは偶然の安定であって、使用として保障されている訳ではありません。

なぜS/4HANA(HANA DB)で取得結果が“ズレ”てしまうのか

S/4 HANAは列指向・インメモリのデータベースです。SAP自身が「SAP HANA is a column-oriented in-memory database」と説明しています。

列型ストレージは、行型(row store)と比べて、データの保持と読み出しの発想が根本的に違います、ざっくり言うと、行型は「1行の塊」を順に読みやすい一方で、列型は「必要な列」だけを高速に読み、圧縮し、分析や集計・大量スキャンに強い設計です。(列型ストレージが圧縮効率に優れることもSAPのHANAドキュメントで説明されています)。

この列型のデータベースは以下のような動きをします。

同じテーブルでも、どの列を使うのか・どんな条件かによって、オプティマイザが「一番早い取り方」を選びます。列ごとに圧縮され、内部的に分裂・並列化された処理の中で、最終的に”行”としてく見られ直されるタイミングが変わりやすい。結果として、ORDEDR BY なしで最初の1件を期待するのは厳しいです。

さらに、S/4 HANAのSQLリファレンスは「ORDER BYなしだと順序は保証されず、LIMIT(件数制限)の結果は変わりうる」と記載されています。

もしS/4環境でECC環境と取得できるレコードが違う現象が起きているのであれば、ECCではたまたま、ディスク配置やインデックス、実行計画の癖によって「いつも同じ行が先に見つかる」状態になっていた可能性が高い。と言えます。

S/4 HANAへの移行で高速化・並列化・アクセスパスが変わり、未定義部分が露呈したというわけです。

適切なコードの書き方

じゃあ、ORDER BYをつければいいかというと、そうではありません。

もし1件のレコードを取得する前にレコードの順序を並べ替えておく必要があるのであれば、ORDER BYとセットで使うべきです。

以下のようなコードで1件のデータを取得することができます。

ABAP
" 最新日付の1件が欲しい:順序を定義して1件に絞る
SELECT matnr ersda
  FROM mara
  WHERE matnr IN @s_matnr
  ORDER BY ersda DESCENDING
  INTO @ls_mara
  UP TO 1 ROWS.
ENDSELECT.

参照リンク

ABAP Keyword Documentation:ORDER BY(ORDER BYなしは順序未定義)

SAP HANA SQL Reference:SELECT(ORDER BYなしは順序保証なし/LIMIT結果が変わり得る)

SAP公式:What is SAP HANA?(HANAは列指向・インメモリDB)

SAP HANA Platform Docs:Columnar Data Storage(列型ストレージと圧縮効率)

SAP Community:SELECT SINGLE vs UP TO 1 ROWS(ORDER BYを使うならUP TO側)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次