表題の通り、やってみるやで彡(゚)(゚)
INSERTするバインド変数の大きさの順番/組み合わせで挙動が変わるので、
まずはバイト数が小さい順にINSERTしてみるやで。
バイト数の小さい順にINSERT
実行するSQLは下記
-- 共有プールをFLUSH
ALTER SYSTEM FLUSH SHARED_POOL;
-- テーブル作成
DROP TABLE TBL_A PURGE;
CREATE TABLE TBL_A(C1 VARCHAR2(4000));
-- 1バイトのバインド変数でINSERT
VAR B1 VARCHAR2(1);
EXEC :B1 := 'A';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- 40バイトのバインド変数でINSERT
VAR B1 VARCHAR2(40);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- 200バイトのバインド変数でINSERT
VAR B1 VARCHAR2(200);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- V$SQLで子カーソルを確認
SET LINESIZE 300;
SET PAGESIZE 100;
COLUMN SQL_TEXT FORMAT A60;
SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
WHERE SQL_ID = 'g47kmy54uf3nm';
-- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
COLUMN BIND_NAME FORMAT A30;
SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = 'g47kmy54uf3nm');
-- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = 'g47kmy54uf3nm';
結果は以下の通り
:
SQL> -- V$SQLで子カーソルを確認
SQL> SET LINESIZE 300;
SQL> SET PAGESIZE 100;
SQL> COLUMN SQL_TEXT FORMAT A60;
SQL> SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
2 WHERE SQL_ID = 'g47kmy54uf3nm';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE CHILD_ADDRESS SQL_TEXT
------------- ------------ --------------- ---------------- -----------------------------
g47kmy54uf3nm 0 0 000000006C45E450 INSERT INTO TBL_A VALUES(:B1) ★1つ目の子カーソル
g47kmy54uf3nm 1 0 000000006CD519E0 INSERT INTO TBL_A VALUES(:B1) ★2つ目の子カーソル
g47kmy54uf3nm 2 0 000000006ECC0660 INSERT INTO TBL_A VALUES(:B1) ★3つ目の子カーソル
SQL> -- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
SQL> COLUMN BIND_NAME FORMAT A30;
SQL> SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
2 WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = 'g47kmy54uf3nm');
ADDRESS POSITION DATATYPE MAX_LENGTH BIND_NAME
---------------- ---------- ---------- ---------- ---------
000000006C45E450 1 1 32 B1 ★バインド変数のMAX_LENGTH値が 32バイト
000000006CD519E0 1 1 128 B1 ★バインド変数のMAX_LENGTH値が 128バイト
000000006ECC0660 1 1 2000 B1 ★バインド変数のMAX_LENGTH値が2000バイト
SQL> -- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SQL> SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
2 FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = 'g47kmy54uf3nm';
SQL_ID CHILD_ADDRESS CHILD_NUMBER H B
------------- ---------------- ------------ - -
g47kmy54uf3nm 000000006C45E450 0 N N
g47kmy54uf3nm 000000006CD519E0 1 Y Y ★HASH_MATCH_FAILED列 と BIND_LENGTH_UPGRADEABLE列が N
g47kmy54uf3nm 000000006ECC0660 2 Y Y ★HASH_MATCH_FAILED列 と BIND_LENGTH_UPGRADEABLE列が N
バイト数の大きい順にINSERT
実行するSQLは下記
-- 共有プールをFLUSH
ALTER SYSTEM FLUSH SHARED_POOL;
-- テーブル作成
DROP TABLE TBL_A PURGE;
CREATE TABLE TBL_A(C1 VARCHAR2(4000));
-- 200バイトのバインド変数でINSERT
VAR B1 VARCHAR2(200);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- 40バイトのバインド変数でINSERT
VAR B1 VARCHAR2(40);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- 1バイトのバインド変数でINSERT
VAR B1 VARCHAR2(1);
EXEC :B1 := 'A';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_A VALUES(:B1);
COMMIT;
-- V$SQLで子カーソルを確認
SET LINESIZE 300;
SET PAGESIZE 100;
COLUMN SQL_TEXT FORMAT A60;
SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
WHERE SQL_ID = 'g47kmy54uf3nm';
-- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
COLUMN BIND_NAME FORMAT A30;
SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = 'g47kmy54uf3nm');
-- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = 'g47kmy54uf3nm';
結果は以下の通りで、子カーソルは1つだけなんですやね彡(゚)(゚)
SQL> -- V$SQLで子カーソルを確認
SQL> SET LINESIZE 300;
SQL> SET PAGESIZE 100;
SQL> COLUMN SQL_TEXT FORMAT A60;
SQL> SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
2 WHERE SQL_ID = 'g47kmy54uf3nm';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE CHILD_ADDRESS SQL_TEXT
------------- ------------ --------------- ---------------- -----------------------------
g47kmy54uf3nm 0 0 000000006EE9F7B8 INSERT INTO TBL_A VALUES(:B1) ★子カーソルは1つだけ
SQL>
SQL> -- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
SQL> COLUMN BIND_NAME FORMAT A30;
SQL> SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
2 WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = 'g47kmy54uf3nm');
ADDRESS POSITION DATATYPE MAX_LENGTH BIND_NAME
---------------- ---------- ---------- ---------- ---------
000000006EE9F7B8 1 1 2000 B1 ★バインド変数のMAX_LENGTH値が2000バイト
SQL>
SQL> -- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SQL> SELECT * FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = 'g47kmy54uf3nm';
SQL_ID ADDRESS CHILD_ADDRESS CHILD_NUMBER U S O O S L F E B P I S T A B D L T B I I R L I O E M U T N F A P T D L D B P C S C P T M B M R O P M F L P L A F L R L H P B U REASON CON_ID
------------- ---------------- ---------------- ------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------------------------------------------------------------------------- ----------
g47kmy54uf3nm 0000000070E32AF8 000000006EE9F7B8 0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0
SQL> SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
2 FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = 'g47kmy54uf3nm';
SQL_ID CHILD_ADDRESS CHILD_NUMBER H B
------------- ---------------- ------------ - -
g47kmy54uf3nm 000000006EE9F7B8 0 N N
複数バインド変数の組み合わせで小さい順にINSERT
複数バインド変数の場合は、それぞれのバインド変数の組み合わせでも
子カーソルが生成されます。以下のSQLを実行してみます。
-- 共有プールをFLUSH
ALTER SYSTEM FLUSH SHARED_POOL;
-- テーブル作成
DROP TABLE TBL_B PURGE;
CREATE TABLE TBL_B(
C1 VARCHAR2(4000)
, C2 VARCHAR2(4000)
);
-- 1バイトのバインド変数*2でINSERT
VAR B1 VARCHAR2(1);
VAR B2 VARCHAR2(1);
EXEC :B1 := 'A';
EXEC :B2 := 'B';
-- sql_id = '5f5u0gky3kjpc'
INSERT INTO TBL_B VALUES(:B1, :B2);
COMMIT;
-- 1バイト&40バイトのバインド変数でINSERT
VAR B1 VARCHAR2(1);
VAR B2 VARCHAR2(40);
EXEC :B1 := 'A';
EXEC :B2 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = '5f5u0gky3kjpc'
INSERT INTO TBL_B VALUES(:B1, :B2);
COMMIT;
-- 40バイト&1バイトのバインド変数でINSERT
VAR B1 VARCHAR2(40);
VAR B2 VARCHAR2(1);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
EXEC :B2 := 'A';
-- sql_id = '5f5u0gky3kjpc'
INSERT INTO TBL_B VALUES(:B1, :B2);
COMMIT;
-- 40バイトのバインド変数*2でINSERT
VAR B1 VARCHAR2(40);
VAR B2 VARCHAR2(40);
EXEC :B1 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
EXEC :B2 := 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
-- sql_id = 'g47kmy54uf3nm'
INSERT INTO TBL_B VALUES(:B1, :B2);
COMMIT;
-- V$SQLで子カーソルを確認
SET LINESIZE 300;
SET PAGESIZE 100;
COLUMN SQL_TEXT FORMAT A60;
SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
WHERE SQL_ID = '5f5u0gky3kjpc';
-- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
COLUMN BIND_NAME FORMAT A30;
SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = '5f5u0gky3kjpc')
ORDER BY ADDRESS, POSITION;
-- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = '5f5u0gky3kjpc';
結果は以下の通りで、複数の子カーソルが生成されるんやで彡(゚)(゚)
SQL> -- V$SQLで子カーソルを確認
SQL> SET LINESIZE 300;
SQL> SET PAGESIZE 100;
SQL> COLUMN SQL_TEXT FORMAT A60;
SQL> SELECT SQL_ID, CHILD_NUMBER, PLAN_HASH_VALUE, CHILD_ADDRESS, SQL_TEXT FROM V$SQL
2 WHERE SQL_ID = '5f5u0gky3kjpc';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE CHILD_ADDRESS SQL_TEXT
------------- ------------ --------------- ---------------- ----------------------------------
5f5u0gky3kjpc 0 0 000000006EB29608 INSERT INTO TBL_B VALUES(:B1, :B2) ★1つ目の子カーソル
5f5u0gky3kjpc 1 0 000000006C94E5C0 INSERT INTO TBL_B VALUES(:B1, :B2) ★2つ目の子カーソル
5f5u0gky3kjpc 2 0 000000006E6F3638 INSERT INTO TBL_B VALUES(:B1, :B2) ★3つ目の子カーソル
SQL>
SQL> -- V$SQL_BIND_METADATAで子カーソルのバインド変数を確認
SQL> COLUMN BIND_NAME FORMAT A30;
SQL> SELECT ADDRESS, POSITION, DATATYPE, MAX_LENGTH, BIND_NAME FROM V$SQL_BIND_METADATA
2 WHERE ADDRESS IN (SELECT CHILD_ADDRESS FROM V$SQL WHERE SQL_ID = '5f5u0gky3kjpc')
3 ORDER BY ADDRESS, POSITION;
ADDRESS POSITION DATATYPE MAX_LENGTH BIND_NAME
---------------- ---------- ---------- ---------- ---------
000000006C94E5C0 1 1 32 B1 ★2つ目の子カーソルのバインド変数定義
000000006C94E5C0 2 1 128 B2 ★2つ目の子カーソルのバインド変数定義
000000006E6F3638 1 1 128 B1 ★3つ目の子カーソルのバインド変数定義
000000006E6F3638 2 1 128 B2 ★3つ目の子カーソルのバインド変数定義
000000006EB29608 1 1 32 B1 ★1つ目の子カーソルのバインド変数定義
000000006EB29608 2 1 32 B2 ★1つ目の子カーソルのバインド変数定義
6 rows selected.
SQL>
SQL> -- V$SQL_SHARED_CURSORで子カーソルの生成理由を確認
SQL> SELECT SQL_ID, CHILD_ADDRESS, CHILD_NUMBER, HASH_MATCH_FAILED, BIND_LENGTH_UPGRADEABLE
2 FROM V$SQL_SHARED_CURSOR WHERE SQL_ID = '5f5u0gky3kjpc';
SQL_ID CHILD_ADDRESS CHILD_NUMBER H B
------------- ---------------- ------------ - -
5f5u0gky3kjpc 000000006EB29608 0 N N
5f5u0gky3kjpc 000000006C94E5C0 1 Y Y
5f5u0gky3kjpc 000000006E6F3638 2 Y Y
という訳で単純なINSERT文でも複数の子カーソルが生成されることを確認できました。
参考資料(マニュアル)
マニュアルも見とくんやで!彡(^)(^)