備忘録

Oracle Database 18c 新機能

Oracle Database 18c マニュアル が公開されていたので、新機能について軽く見た。

12c に比べると、アプリ屋に関する新機能が極端に少ない(OLAP向けだから?OLTP でも Core の Database エンジンは同じだとおもうが)。
次は、少ないものの中から目にとまったもの。

■Private Temporary Tables

Private temporary tables are temporary database objects that are automatically dropped at the end of a transaction or a session.


MySQL の 一時表みたいにテーブルが消えるんですね。いらん機能ですね。createした時トランザクションどうなるの?
MySQL の案件で Oracle の一時表と同じことが出来ずムカついた。
いちいちテーブルを作らないといけない、コネクションプールを使っているの残っている可能性があるなど。

■Manual termination of Run-Away Queries

This feature enables the database administrator to terminate a runaway SQL query using the ALTER SYSTEM CANCEL SQL statement.
This frees the system resources consumed by the runaway SQL query so that other SQL queries can use them.


kill する時と同じで、session,serial# は必須で、sql_id はオプション。sql_id指定したとして、そのセッションのトランザクションがどうなるか謎。マニュアルに特に書かれていないし。
これも使い道、思いつかず。

FIXED_DATE

マニュアルを見ていたら、「FIXED_DATE」というのを見つけた。

ALTER SYSTEM SET FIXED_DATE = '2018-03-19-00:00:0' SCOPE = MEMORY;


とかで SYSDATE の返す値を固定にできるそうだ。
戻すには

ALTER SYSTEM SET FIXED_DATE = NONE SCOPE = MEMORY;


とする。
ふ~ん。でも、使えんね。

  • SYSTIMESTAMP は変更できない(できるパラメータもなさそう)
  • SYSTEM 単位でしか変更できない。共用だからそんな簡単に変更できないし。ALTER SESSIONでできるならまだね。

ちゃんとしたシステム作るなら、ファイルなり・DBなりで運用日付持つでしょうね。
どこまで細かい単位で持つかは設計思想だけど、バッチとオンライン用に2つは持つだろうね。
オンラインは試験用だろうけど、バッチは実運用で必要ね。

APPEND ヒントの誤った使い方

APPENDヒント」というのがある。
DIRECT PATH INSERT してね、っというヒントである。
DIRECT PATHの何がうれしいかと言うと、バッファキャッシュを経由せずに直接データファイルに書き込むので速いというメリットがある。
しかし、主に次のデメリットがある。
①HWMが上がる。
 ⇒データファイルが膨れるばかり。
②テーブル(パーティション)をロックする
 ⇒同時実行性が制限される
③コミットしないとINSERTしたレコードを参照できない
ダイレクト・パス・インサートの使用上の注意」にまとめられている。
アプリを組む上で、②③が特に問題になる。

③でおバカな作りになっているストアドプロシージャを最近見た。

1つのプロシージャでDIRECT INSERT&COMMITして、その後別の処理をした後COMMITしている。
1個目のトランザクションの後でエラーとなった時にリカバリーできる作りになっていないのである。
DIRECT INSERTしたものを手で消さないとリラん出来ないダメな作り。
しかも、DIRECT INSERTがそれほど大量の書き込みではないと来る。

TRUNCATE⇒DIRECT INSERT みたいに、一時表では役に立たない場合のワークテーブルへの書き込みになどに限定して使うべき。

ただのINSERT INTO VALUESにAPPENDヒントを付けてあるケースもあった。
APPEND_VALUESヒント」じゃないと効かんのによ。
何も考えず、何も理解せず実装しているんだな~というのが良くわかる。

APPEND_VALUES も1件登録するだけのSQLには意味がなく、
バルクインサートするなどチューニングしても性能要件を満たせない場合に+αとして使うべき。
マニュアルにも次のように書いてあるしね。

APPEND_VALUESヒントを使用すると、パフォーマンスを大幅に向上できます。次に使用方法の例を示します
・ Oracle Call Interface(OCI)を使用するプログラムで、大規模な配列バインドまたは行コールバックを伴う配列バインドを使用する場合
・PL/SQLで、VALUES句とともにINSERT文を使用するFORALLループを伴う多くの行をロードする場合

外部表

この前、はじめて外部表を使ったのでその時のメモ。

・SQL*Loaderでやるより、外部表からSELECT/INSERTで登録する方が大分速い。
 従来型(Direct Pathでない)のLoaderと比べて1/5位の時間で済んだ。

・CREATEする時には特にエラーは起きず、SELECTする時にファイルの形式がおかしかったりするとエラーが発生する。

・SQL*Loaderタイプ(デフォルト)とDATA Pumpタイプのアクセス・ドライバがある。
 SQL*Loaderタイプは、Loaderと一緒の動きをすると思ったが、最終項目が空(「あああ,いいい,」みたいに終わると)だと次のようなエラーになる。

KUP-04021: field formatting error for field Col1
KUP-04023: field start is after end of record
KUP-04101: record 2 rejected in file /home/oracle/datafiles/example.dat


 耳「"」付きの場合は大丈夫。
 「MISSING FIELD VALUES ARE NULL」というオプションが必要。
そんなことは、「SQL*Loaderと外部表との処理内容の違い」に一言も書かれていない。

・外部表を作っても、対象のファイルはロックされない。
 移動したり、消したりすると外部表に SELECT した時エラーとなる。その状態で外部表を放置してたら、
 Oracleの内部ジョブが何かのタイミングでアクセスしてALERTログが出た。

・複数回アクセスする場合は、いったんワークテーブルに書き写した方が良い。マニュアルかどこかのサイトに書いてあった。
 まあ、その通りだろう。バイナリでファイルロックしてあるわけでないので、都度パースする必要があるからね。

・制約をつけられない

・LOCK TABLEできない

指定した精度より小さい桁に値を設定すると四捨五入される

create table T ( C number(3));
insert into t values (123.5);
select * from t;
としたとき、123が取れると思ったが、124となった。
指定した精度より下は無視されるのが正しいと思うが。。
マニュアルを見ると四捨五入の例があった。

入力:7,456,123.89
指定:NUMBER(9,1)
格納方法 :7456123.9

試したら、TIMESTAMPも精度を指定でき、同じような動きになった。
次のページ

FC2Ad