ssh で ProxyCommandが動かない問題の解決

ssh で多段ポートフォワーディングやプロキシを通す時に、~/.ssh/configにProxyCommandを設定してsshコマンドを実行しようとしたところ、下記のようなエラーが発生した。

$ ssh hoge
zsh: No such file or directory
write: Broken pipe

むむ、と思い、取り合えずデバッグモードで実行してみても..

$ ssh hoge -vvv
...
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Executing proxy command: exec ssh -CW 192.168.56.112:22 hoge
debug1: permanently_drop_suid: 197609
zsh: No such file or directory
...

エラーを見る限り、ProxyCommand内に設定しているコマンドを見つけることが出来ないのではなく、zsh自体のパスが解決できていない模様。

$SHELLを見てみると zshとなっている。

$ echo $SHELL
zsh

これをフルパスに直して実行すると、問題なく実行できた。

$ export SHELL=/bin/zsh
$ ssh hoge

Oracle Linuxのバージョンを知る方法

RHEL系のOSの場合以下のファイルをcatすることでバーションを知ることができる。

/etc/*-release

Oracle Linuxの場合は以下の通り

$ ls /etc/*release
/etc/oracle-release  /etc/os-release  /etc/redhat-release  /etc/system-release
$cat /etc/os-release 

NAME="Oracle Linux Server"
VERSION="7.3"
ID="ol"
VERSION_ID="7.3"
PRETTY_NAME="Oracle Linux Server 7.3"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:7:3:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://bugzilla.oracle.com/"

ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7"
ORACLE_BUGZILLA_PRODUCT_VERSION=7.3
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=7.3

$ cat /etc/oracle-release
Oracle Linux Server release 7.3

apache zeppelinでsparkが動かない問題(Service 'sparkDriver' could not bind on port 0. Attempting port 1. )の解決

apache zeppelin https://zeppelin.apache.org/チュートリアルを実行しようとした際に、ハマったのでメモ。

zeppelinはjypter notebookみたいにウェブブラウザから様々な言語(R, python, scala)やツール(spark, bigquery, hadoop等)を実行できる環境のこと。 チュートリアルとしてsparkを動かすものがあるのだが、これがエラーになっており動かない。

ログを確認すると以下のように表示されている

WARN Utils: Service 'sparkDriver' could not bind on port 0. Attempting port 1.
ERROR SparkContext: Error initializing SparkContext.

これの原因はapache zeppelinがインストールされているサーバのホストネームの設定が誤っていること。 一度誤った固定IPとそれに紐づくドメインを設定していて、そのままになっていたのを忘れていた。

誤ったIP: 196.18.35.2 誤ったドメイン: tmks0828.jp.example.com 正しいIP: 196.18.35.1 正しいドメイン: tmks0820.jp.example.com

サーバのホストネームの設定と/etc/hostsの記述を変更する

$ hostname
tmks0828.jp.example.com

$ hostname tmks0820.jp.example.com

$ hostname
tmks0820.jp.example.com

$ vim /etc/hosts

....
196.18.35.1 tmks0820.jp.example.com
....

zeppelinを再起動すると、チュートリアルのsparkを実行することが出来た。

組み込みのPL/SQLプロシージャ(ファンクション)の引数を確認する

PL/SQLの組み込み、もしくは自作プロシージャおよびファンクションの引数がどうなっているのか確認するのに最も早いのは、ドキュメントを確認することです。しかし、何かしらの理由でドキュメントを確認できない(ローカルにドキュメントがなく、ネットワークに接続することが出来ない等)場合やそもそもいちいちドキュメントを見に行かずにsqlplusで手っ取り早く確認したい(私はこのパターンです。脳内コンテキストスイッチが発生するのが非常に嫌だ。)場合があると思います。 意外と検索しても情報が出てこないので、やり方を記載します。

PL/SQLプロシージャ(ファンクション)の引数の確認方法

  • [DBA|ALL|USER]_ARGUMENTSビューを参照します。
  • [DBA|ALL|USER]_ARGUMENTSの定義は以下の通り
SYS@ORCL > desc all_arguments
 名前                                                NULL?    型
 ----------------------------------------------------- -------- ------------------------------------
 OWNER                                                 NOT NULL VARCHAR2(128)
 OBJECT_NAME                                                    VARCHAR2(128)
 PACKAGE_NAME                                                   VARCHAR2(128)
 OBJECT_ID                                             NOT NULL NUMBER
 OVERLOAD                                                       VARCHAR2(40)
 SUBPROGRAM_ID                                                  NUMBER
 ARGUMENT_NAME                                                  VARCHAR2(128)
 POSITION                                              NOT NULL NUMBER
 SEQUENCE                                              NOT NULL NUMBER
 DATA_LEVEL                                            NOT NULL NUMBER
 DATA_TYPE                                                      VARCHAR2(30)
 DEFAULTED                                                      VARCHAR2(1)
 DEFAULT_VALUE                                                  LONG
 DEFAULT_LENGTH                                                 NUMBER
 IN_OUT                                                         VARCHAR2(9)
 DATA_LENGTH                                                    NUMBER
 DATA_PRECISION                                                 NUMBER
 DATA_SCALE                                                     NUMBER
 RADIX                                                          NUMBER
 CHARACTER_SET_NAME                                             VARCHAR2(44)
 TYPE_OWNER                                                     VARCHAR2(128)
 TYPE_NAME                                                      VARCHAR2(128)
 TYPE_SUBNAME                                                   VARCHAR2(128)
 TYPE_LINK                                                      VARCHAR2(128)
 PLS_TYPE                                                       VARCHAR2(128)
 CHAR_LENGTH                                                    NUMBER
 CHAR_USED                                                      VARCHAR2(1)
 ORIGIN_CON_ID                                                  NUMBER
  • 例えばDBMS_SQLTUNEパッケージのCREATE_TUNING_TASKプロシージャの引数を確認したいケースでは以下のようにします。
set linesize 1000
set pagesize 1000
col object_name for a20
col overload for a2
col argument_name for a20
col default_value for a20

select object_name
     , overload
     , argument_name
     , position
     , data_type
     , defaulted
     , default_value
     , in_out
from   all_arguments
where package_name = 'DBMS_SQLTUNE'
and   object_name = 'CREATE_TUNING_TASK'
order by overload, position;
OBJECT_NAME          OV ARGUMENT_NAME          POSITION DATA_TYPE                      D DEFAULT_VALUE        IN_OUT
-------------------- -- -------------------- ---------- ------------------------------ - -------------------- ---------
CREATE_TUNING_TASK   1                                0 VARCHAR2                       N                      OUT
CREATE_TUNING_TASK   1  SQL_TEXT                      1 CLOB                           N                      IN
CREATE_TUNING_TASK   1                                1 OPAQUE/XMLTYPE                 Y                      IN
CREATE_TUNING_TASK   1  BIND_LIST                     2 VARRAY                         Y                      IN
CREATE_TUNING_TASK   1  USER_NAME                     3 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   1  SCOPE                         4 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   1  TIME_LIMIT                    5 NUMBER                         Y                      IN
CREATE_TUNING_TASK   1  TASK_NAME                     6 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   1  DESCRIPTION                   7 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   1  CON_NAME                      8 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   2                                0 VARCHAR2                       N                      OUT
CREATE_TUNING_TASK   2  SQL_ID                        1 VARCHAR2                       N                      IN
CREATE_TUNING_TASK   2  PLAN_HASH_VALUE               2 NUMBER                         Y                      IN
CREATE_TUNING_TASK   2  SCOPE                         3 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   2  TIME_LIMIT                    4 NUMBER                         Y                      IN
CREATE_TUNING_TASK   2  TASK_NAME                     5 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   2  DESCRIPTION                   6 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   2  CON_NAME                      7 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   3                                0 VARCHAR2                       N                      OUT
CREATE_TUNING_TASK   3  BEGIN_SNAP                    1 NUMBER                         N                      IN
CREATE_TUNING_TASK   3  END_SNAP                      2 NUMBER                         N                      IN
CREATE_TUNING_TASK   3  SQL_ID                        3 VARCHAR2                       N                      IN
CREATE_TUNING_TASK   3  PLAN_HASH_VALUE               4 NUMBER                         Y                      IN
CREATE_TUNING_TASK   3  SCOPE                         5 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   3  TIME_LIMIT                    6 NUMBER                         Y                      IN
CREATE_TUNING_TASK   3  TASK_NAME                     7 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   3  DESCRIPTION                   8 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   3  CON_NAME                      9 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4                                0 VARCHAR2                       N                      OUT
CREATE_TUNING_TASK   4  SQLSET_NAME                   1 VARCHAR2                       N                      IN
CREATE_TUNING_TASK   4  BASIC_FILTER                  2 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  OBJECT_FILTER                 3 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  RANK1                         4 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  RANK2                         5 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  RANK3                         6 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  RESULT_PERCENTAGE             7 NUMBER                         Y                      IN
CREATE_TUNING_TASK   4  RESULT_LIMIT                  8 NUMBER                         Y                      IN
CREATE_TUNING_TASK   4  SCOPE                         9 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  TIME_LIMIT                   10 NUMBER                         Y                      IN
CREATE_TUNING_TASK   4  TASK_NAME                    11 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  DESCRIPTION                  12 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  PLAN_FILTER                  13 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   4  SQLSET_OWNER                 14 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   5                                0 VARCHAR2                       N                      OUT
CREATE_TUNING_TASK   5  SPA_TASK_NAME                 1 VARCHAR2                       N                      IN
CREATE_TUNING_TASK   5  SPA_TASK_OWNER                2 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   5  SPA_COMPARE_EXEC              3 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   5  BASIC_FILTER                  4 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   5  TIME_LIMIT                    5 NUMBER                         Y                      IN
CREATE_TUNING_TASK   5  TASK_NAME                     6 VARCHAR2                       Y                      IN
CREATE_TUNING_TASK   5  DESCRIPTION                   7 VARCHAR2                       Y                      IN

databaseの作成 12c

必要な環境変数の設定

  • シェルがbashの場合
# ~/.bash_profile
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/12.1.0/dbhome_1
ORACLE_SID=O12C
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$ORACLE_HOME/bin

export PATH

パスワードファイルの作成

$ cd $ORACLE_HOME/dbs
$ orapwd file=orapwO12C.ora

初期化パラメータファイルの作成

$ vi $ORACLE_HOME/dbs

db_name='O12C'
memory_target=1G
processes=150
db_block_size=8192
db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
db_recovery_file_dest_size=2G
diagnostic_dest='/u01/app/oracle/'
dispatchers='(PROTOCOL=TCP)(SERVICE=O12CXDB)'
open_cursors=300
remote_login_passwordfile='EXCLUSIVE'
undo_tablespace='UNDOTBS1'
control_files=('/u01/ctlfile/O12C/control01.ctl', '/u02/ctlfile/O12C/control02.ctl')

データベースに接続 & サーバパラメータファイルの作成

$ sqlplus /nolog
SQL> conn / as sysdba
SQL> create spfile from pfile;

データベースをnomountで起動

SQL> startup nomount

CREATE DATABASE文を実行

SQL> CREATE DATABASE O12C
  MAXLOGFILES 16
  MAXLOGMEMBERS 4
  MAXDATAFILES 1024
  MAXLOGHISTORY 680
  CHARACTER SET AL32UTF8
DATAFILE
  '/u01/dbfile/O12C/system01.dbf'
    SIZE 500M REUSE
    EXTENT MANAGEMENT LOCAL
UNDO TABLESPACE undotbs1 DATAFILE
  '/u02/dbfile/O12C/undobs01.dbf'
    SIZE 800M
SYSAUX DATAFILE
  '/u01/dbfile/O12C/sysaux01.dbf'
    SIZE 500M
DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE
  '/u02/dbfile/O12C/temp01.dbf'
    SIZE 500M
DEFAULT TABLESPACE USERS DATAFILE
  '/u01/dbfile/O12C/users01.dbf'
  SIZE 50M
LOGFILE GROUP 1
  ('/u01/oraredo/O12C/redo01a.rdo',
   '/u02/oraredo/O12C/redo02a.rdo') SIZE 200M,
  GROUP 2
  ('/u01/oraredo/O12C/redo01b.rdo',
   '/u02/oraredo/O12C/redo02b.rdo') SIZE 200M,
  GROUP 3
  ('/u01/oraredo/O12C/redo01c.rdo',
   '/u02/oraredo/O12C/redo02c.rdo') SIZE 200M
USER SYS IDENTIFIED BY Welcome#1
USER SYSTEM IDENTIFIED BY Welcome#1;

必要なスクリプトを実行

SQL> conn / as sysdba
SQL> @?/rdbms/admin/catalog
SQL> @?/rdbms/admin/catproc
SQL> @?/rdbms/admin/utlrp
SQL> conn system/Welcome#1
SQL> @?/sqlplus/admin/pupbtl

動的サンプリング

Why 動的サンプリング

  • サンプル時間は、全体のクエリ実行時間に比べて小さい。
  • 現在のデータベースの統計だけでは最適なプランが作成されないため、動的サンプリングによってパフォーマンスが向上します。
  • クエリは複数回実行される可能性があるため、最初の解析フェーズで少し遅れると全体的にかなりの節約につながります。

When 動的サンプリング

  • 以下のような場合、再帰SQLを使用してデータをサンプリングし、同様のパターンを持つSQL文の間で永続化および共有化できる動的統計を生成します。

  - 欠落統計:欠落しているデータベース統計がある場合、動的統計がサンプリングされます。新しく作成されたオブジェクトであるか、または統計が収集される前に統計がロックされているために欠落している可能性があります。動的統計がオプティマイザに役立つはずですが、これらの統計は従来のデータベース統計と比較して低品質とみなされます。

  - 古い統計:統計が最後に収集されてから表の10%以上の行が変更された場合、統計は古いとみなされます。失効した統計値は、表の行数の変更や、重複した値の数、上位および下位の列値などの列統計の不正確さのために、カーディナリティーの見積もりに影響する可能性があります。

  - 不十分な統計:既存のデータベース統計は、最適な実行計画を生成するには不十分です。短期的には、動的統計は、列のグループや式の拡張統計がないことや、データスキューを特定するヒストグラムがないことを補うことができます。必要な統計がすべて存在する場合でも、複雑な述部、操作または結合のためにカーディナリティを正しく見積もることができない可能性があるため、動的サンプリングが必要な場合があります。

  - パラレル実行:パラレル実行は、通常、長時間実行されるプロセスを高速化するために使用されます。長期実行プロセスの場合、動的統計のサンプリングに関連する時間はクエリの実行時間に比べて些細なので、実行計画が最適であることを確認するために少し時間を費やす価値があります。

  - SQL計画ディレクティブ:1つ以上の使用可能なSQLプラン・ディレクティブが存在すると、動的統計のサンプリングがトリガーされます。 SQLプラン・ディレクティブは、オプティマイザが、前回のSQL文の実行または類似の問合せ式を使用した文からの操作または並列度(DOP)のカーディナリティでの偽装を識別すると作成されます。

設定

  • 動的統計は、OPTIMIZER_DYNAMIC_SAMPLING初期化パラメータとDYNAMIC_SAMPLINGヒントによって制御できます。ここでは、個々の設定に関連する機能について説明します。次の例は、システム、セッション、および文レベルで動的統計を制御する方法を示しています。
ALTER SYSTEM SET OPTIMIZER_DYNAMIC_SAMPLING=11;
ALTER SESSION SET OPTIMIZER_DYNAMIC_SAMPLING=11;

SELECT /*+ dynamic_sampling(users 11) */ * from users;
  • ほとんどの場合、デフォルト値 “2"を変更する必要はありません。これは、SQL計画ディレクティブの導入とその働きにより、Oracle 12cではもっと真実かもしれません。オプティマイザが操作の重複度または並列度(DOP)の誤った点を特定した場合、SQL計画ディレクティブを作成して短期間で動的サンプリングを強制することができます。 SQL計画ディレクティブが存在すると、DBMS_STATSが統計を収集する方法に影響し、データベース統計の問題の根本原因を修正し、SQL計画ディレクティブを作成し、動的サンプリングを不要にします。

  • 動的統計は、V$SQL_REOPTIMIZATION_HINTSビューのOPT_ESTIMATEヒ ントとしてSGAに格納できます。ビューとOPT_ESTIMATEヒントの両方が文書化されていません。動的統計の格納は、同じ文が再度解析された場合、統計の再サンプリングを行う必要がないことを意味します。

SELECT HINT_TEXT FROM V$SQL_REOPTIMIZATION_HINTS;

HINT_TEXT
---------------------------------------------------------------------------------------------------------------------------
OPT_ESTIMATE (@"SEL$2" TABLE "KOKBF$0"@"SEL$2" ROWS=26.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("S"@"SEL$2" "CO"@"SEL$2" "CU"@"SEL$2" "CX"@"SEL$2" "TS"@"SEL$2" "T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=10.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("CO"@"SEL$2" "CU"@"SEL$2" "CX"@"SEL$2" "TS"@"SEL$2" "T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=1.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("CU"@"SEL$2" "CX"@"SEL$2" "TS"@"SEL$2" "T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=10.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("CX"@"SEL$2" "TS"@"SEL$2" "T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=1.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("TS"@"SEL$2" "T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=10.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("T"@"SEL$2" "O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=10.000000 )
OPT_ESTIMATE (@"SEL$7ABE1C4F" JOIN ("O"@"SEL$2" "KSPPCV"@"SEL$2" "KSPPI"@"SEL$2") ROWS=43.000000 )
OPT_ESTIMATE (@"SEL$2" TABLE "O"@"SEL$2" MIN=43.000000 )

パーティショニングに関して②

続きです。

Systemパーティショニング

  • Oracle Databaseによって制御されずにアプリケーション側で制御する必要性のあるパーティショニング
  • 例えば、どのパーティションにデータを挿入するか指定しないとエラーになります。

SYSTEMパーティショニングの作成

CREATE TABLE system_partitioned_tab (
  id           NUMBER,
  code         VARCHAR2(10),
  description  VARCHAR2(50),
  created_date DATE
)
PARTITION BY SYSTEM
(
  PARTITION sort_1,
  PARTITION sort_2
);

データの挿入

INSERT INTO system_partitioned_tab PARTITION (sort_1) VALUES (1, 'ONE', 'ONE', SYSDATE);
INSERT INTO system_partitioned_tab PARTITION (sort_2) VALUES (2, 'TWO', 'TOW', SYSDATE);
COMMIT;

EXEC DBMS_STATS.gather_table_stats(USER, 'SYSTEM_PARTITIONED_TAB');

col table_name for a25
col partition_name for a20
col high_value for a10

SELECT table_name, partition_name, high_value, num_rows
FROM user_tab_partitions
ORDER BY table_name, partition_name;
TABLE_NAME                PARTITION_NAME       HIGH_VALUE   NUM_ROWS
------------------------- -------------------- ---------- ----------
SYSTEM_PARTITIONED_TAB    SORT_1                                   1
SYSTEM_PARTITIONED_TAB    SORT_2                                   1

参照パーティション

参照パーティションの作成

CREATE TABLE parent_tab (
  id           NUMBER       NOT NULL,
  code         VARCHAR2(10) NOT NULL,
  description  VARCHAR2(50),
  created_date DATE,
  CONSTRAINT parent_tab_pk PRIMARY KEY (id)
)
PARTITION BY RANGE (created_date)
(
  PARTITION part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018', 'DD-MON-YYYY')),
  PARTITION part_2018 VALUES LESS THAN (TO_DATE('01-JAN-2019', 'DD-MON-YYYY'))
);

CREATE TABLE child_tab (
  id            NUMBER NOT NULL,
  parent_tab_id NUMBER NOT NULL,
  code          VARCHAR2(10),
  description   VARCHAR2(50),
  created_date  DATE,
  CONSTRAINT child_parent_tab_pk PRIMARY KEY (id),
  CONSTRAINT child_parent_tab_fk FOREIGN KEY (parent_tab_id) REFERENCES parent_tab (id)
) 
PARTITION BY REFERENCE (child_parent_tab_fk);

データの挿入

INSERT INTO parent_tab VALUES (1, 'ONE', '1 ONE', SYSDATE);
INSERT INTO parent_tab VALUES (2, 'TWO', '2 TWO', SYSDATE);
INSERT INTO parent_tab VALUES (3, 'THREE', '3 THREE', ADD_MONTHS(SYSDATE, 12));

INSERT INTO child_tab VALUES (1, 1, 'ONE', '1 1 ONE', SYSDATE);
INSERT INTO child_tab VALUES (2, 3, 'TWO', '2 3 TWO', SYSDATE);
INSERT INTO child_tab VALUES (3, 3, 'THREE', '3 3 THREE', SYSDATE);

COMMIT;
EXEC DBMS_STATS.gather_table_stats(USER, 'PARENT_TAB');
EXEC DBMS_STATS.gather_table_stats(USER, 'CHILD_TAB');

データの確認

col table_name for a20
col partition_name for a20
col tablespace_name for a20

SELECT table_name, partition_name, high_value, num_rows
FROM user_tab_partitions;
TABLE_NAME           PARTITION_NAME       HIGH_VALUE                       NUM_ROWS
-------------------- -------------------- ------------------------------ ----------
CHILD_TAB            PART_2017                                                    1
CHILD_TAB            PART_2018                                                    2
PARENT_TAB           PART_2017            TO_DATE(' 2018-01-01 00:00:00'          2
                                          , 'SYYYY-MM-DD HH24:MI:SS', 'N
                                          LS_CALENDAR=GREGORIAN')

PARENT_TAB           PART_2018            TO_DATE(' 2019-01-01 00:00:00'          1
                                          , 'SYYYY-MM-DD HH24:MI:SS', 'N
                                          LS_CALENDAR=GREGORIAN')

仮想列パーティション

仮想列パーティション表の作成

  • NLS_LENGTH_SEMANTICSをCHARに設定する必要性があります。
alter session set nls_length_semantics='CHAR';
CREATE TABLE users (
  id           NUMBER,
  username     VARCHAR2(20),
  first_letter VARCHAR2(1)
    GENERATED ALWAYS AS
      (
        UPPER(SUBSTR(TRIM(username), 1, 1))
      ) VIRTUAL
)
PARTITION BY LIST (first_letter)
(
  PARTITION part_a_g VALUES ('A','B','C','D','E','F','G'),
  PARTITION part_h_n VALUES ('H','I','J','K','L','M','N'),
  PARTITION part_o_u VALUES ('O','P','Q','R','S','T','U'),
  PARTITION part_v_z VALUES ('V','W','X','Y','Z')
);

データの挿入

INSERT INTO users (id, username) VALUES (1, 'Andy Pandy');
INSERT INTO users (id, username) VALUES (1, 'Burty Basset');
INSERT INTO users (id, username) VALUES (1, 'Harry, Hill');
INSERT INTO users (id, username) VALUES (1, 'Iggy Pop');
INSERT INTO users (id, username) VALUES (1, 'Oliber Hardy');
INSERT INTO users (id, username) VALUES (1, 'Peter Pervis');
INSERT INTO users (id, username) VALUES (1, 'Veruca Salt');
INSERT INTO users (id, username) VALUES (1, 'Wiley Cyote');
COMMIT;

EXEC DBMS_STATS.gather_table_stats(USER, 'USERS');

データの確認

col table_name for a25
col partition_name for a20
col high_value for a40

SELECT table_name, partition_name, high_value, num_rows
FROM  user_tab_partitions
ORDER BY table_name, partition_name;
TABLE_NAME                PARTITION_NAME       HIGH_VALUE                                 NUM_ROWS
------------------------- -------------------- ---------------------------------------- ----------
USERS                     PART_A_G             'A', 'B', 'C', 'D', 'E', 'F', 'G'                 2
USERS                     PART_H_N             'H', 'I', 'J', 'K', 'L', 'M', 'N'                 2
USERS                     PART_O_U             'O', 'P', 'Q', 'R', 'S', 'T', 'U'                 2
USERS                     PART_V_Z             'V', 'W', 'X', 'Y', 'Z'                           2