Introduction of Oracle Database Architecture

43
2015313株式会社コーソル 渡部 亮太 Introduction of Oracle Database Architecture

Transcript of Introduction of Oracle Database Architecture

2015年3月13日

株式会社コーソル 渡部 亮太

Introduction of

Oracle Database Architecture

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 1

Agenda

I. OracleアーキテクチャとSQL処理

II. データとファイルI/O

III. テーブル、索引と実行計画

IV. オプティマイザ統計

V. データベースバッファキャッシュ

VI. SQLの解析と共有プール

VII. ソートとPGA、一時表領域

VIII.まとめ

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 2

RDBMSとは / Oracle Databaseとは

• RDBMS(Relational Database Management

System) =表(テーブル)形式のデータを保管するデータベース管理システム

• データ操作用の言語SQLを用いて、クライアントアプリケーションからデータの検索および更新を実行できる

• Oracle DatabaseはRDBMS製品の1つ

テーブル

id ename ・・・

87 Steven ・・・

204 Hermann ・・・

ABC xxx ・・・

クライアント

アプリケーション

id ename ・・・

87 Steven ・・・

204 Hermann ・・・

205 Shelly ・・・

SELECT …

① SQL発行

②検索結果

RDBMS

以後 "Oracle Database"を"Oracle"と略記

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 3

Oracleアーキテクチャ

セッション SGA

SQLの発行

実行結果の返送

データファイル

サーバープロセス

クライアント

アプリケーション

データベース

バッファ

キャッシュ

共有

プール

PGA

SQL実行

セッション

SQLの発行

実行結果の返送

サーバープロセス

クライアント

アプリケーション

SQL実行

専用サーバープロセス接続の場合

SGAの構成コンポーネントは省略して記載

一時ファイル

SQL>

PGA

SQL(SELECT)に関連する構成要素のみを抜粋

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 4

SQL処理の全体像

SGA

データファイル

クライアント

アプリケーション

データベース

バッファ

キャッシュ

共有

プール

一時ファイル

サーバープロセス

解析

PGA

1 2 3 4

1 2 3 4

① SQL発行

SELECT …

フェッチ

②解析結果を共有プールに保管

③データファイルから

データを取得&キャッシュ

④(必要な場合) データをソート

⑤ 検索結果

を返送

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 5

Oracleアーキテクチャ - クライアントAPとセッション

• クライアントアプリケーションからの1つの接続に対して、1つのサーバープロセスが起動し、1つのセッションが確立される

• 1つのセッションを介して発行されたSQLは、対応するサーバープロセスで実行される

• (この接続形態を専用サーバー接続と呼ぶ)

セッション SGA

SQLの発行

実行結果の返送

サーバープロセス

クライアント

アプリケーション

データベース

バッファ

キャッシュ

共有

プール

PGA

SQL実行

セッション

SQLの発行

実行結果の返送

サーバープロセス

クライアント

アプリケーション

SQL実行 SQL>

PGA

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 6

V$SESSION

• V$ビュー(動的パフォーマンスビュー)はOracleの内部状態を確認できる特殊なビュー

• V$SESSIONからセッションの状態が確認できる

主要な列名 確認できる情報

SID セッションID

SERIAL# SIDとSERIAL#でセッションを一意に識別できる

USERNAME Oracleユーザー名

PROGRAM クライアントアプリケーションの情報

TYPE 'USER' : Oracleユーザーの接続

'BACKGROUND' : バックグラウンドプロセスの接続

EVENT 発生している待機イベント

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 7

Oracleアーキテクチャ - データ・記憶域構造

表領域

テーブル

データファイル

データブロック

行データ

id ename ・・・

87 Steven ・・・

204 Hermann ・・・

205 Shelly ・・・

1つの表領域が複数のデータファイルから構成される場合もあります

行データ

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 8

SQLの実行とファイルI/O

セッション

SGA SQLの発行

実行結果の返送

データファイル

サーバープロセス

SQL実行

クライアント

アプリケーション

データベースバッファキャッシュ

データブロック

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 9

Oracleのテーブル(ヒープ構成表)

• テーブルに格納される行の順序は不定

– ある行の位置を特定できない

• ある行を取得したい場合の処理

1. テーブルのHWM以下の全ブロックを読み出し

(=TABLE ACCESS FULL、

いわゆるテーブルフルスキャン)

2. 条件に合致した行のみを抽出

(=filter)

• データ量が多い場合はI/Oが大量に発生し、非効率

– テーブルフルスキャンは一般に避けるべき

ブロック1

ブロック2

id name ・・・

87 Steven ・・・

27 Hermann ・・・

21 Shelly ・・・

id name ・・・

20 Neena ・・・

3 Lex ・・・

1 William ・・・

ブロックn

id name ・・・

103 Alexandar ・・・

105 David ・・・

203 Susan ・・・

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 10

デモ:データ1行取得のためにテーブルフルスキャン

-- 30000行のデータを持つテーブルを作成

set autotrace off

drop table testtbl;

create table testtbl

( id number, n number, name varchar(80), color varchar(4), dummy1 char(2000));

insert into testtbl select level, TRUNC(DBMS_RANDOM.VALUE * 1000), 'aaa', 'red', 'xxx' from dual connect by level <= 30000;

commit;

exec dbms_stats.gather_table_stats(NULL,'TESTTBL');

SELECT count(*) FROM testtbl;

-- id=1の行(1行)をSELECT → TABLE ACCESS FULL + filter

set autotrace on

set timing on

alter system flush buffer_cache;

SELECT id, name FROM testtbl WHERE id = 1;

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 11

索引の仕組み

<DBA5>

<DBA9> <DBA4>

id=1 ブロック1

ブロック2

rowid5

id=1

索引

ルートブロック

ブランチブロック

リーフブロック

<DBA8>

ROWID id name ・・・

rowid0 87 Steven ・・・

rowid1 27 Hermann ・・・

rowid2 21 Shelly ・・・

id アドレス

~199 DBA5

~340 DBA…

803~ DBA…

ROWID id name ・・・

rowid3 20 Neena ・・・

rowid4 3 Lex ・・・

rowid5 1 William ・・・

id アドレス

~20 DBA9

~35 DBA8

175~ DBA4

id アドレス

1 rowid5

3 rowid4

20 rowid3

id アドレス

21 rowid2

27 rowid1

35 rowid9

id アドレス

175 rowid6

177 rowid8

199 rowid9

索引を用いたアクセス

INDEX UNIQUE SCANオペレーション

TABLE ACCESS BY INDEX ROWID (BATCHED) オペレーション

A

B

ブロックn

ROWID id name ・・・

rowid97 103 Alexandar ・・・

rowid98 105 David ・・・

rowid99 203 Susan ・・・

C

A

id=1

B

表を用いたアクセス

TABLE FULL SCANオペレーション C

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 12

実行計画とは

• 実行計画は、SQLがOracleで実行される手順を示す

• 実行計画はコストベースオプティマイザ(CBO; Cost-Based

Optimizer)が作成する

– CBOはOracleの内部コンポーネント

– オプティマイザ統計が最新でないと適切な実行計画が作成されないことに注意

• 意図したパフォーマンスが得られない場合、想定した実行計画で実行されているかチェックする必要がある

-------------------------------------------------------------- | Id | Operation | Name | Rows |... | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | |... | | 1 | NESTED LOOPS | | 2 |... | |* 2 | TABLE ACCESS FULL | PA | 1 |... | | 3 | TABLE ACCESS BY INDEX ROWID| CH | 2 |... | |* 4 | INDEX RANGE SCAN | IDX_CHPA | 2 |... | --------------------------------------------------------------

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 13

デモ:索引を作成して実行計画の変化をみる

-- id列に索引を作成

create index testidx1 on testtbl(id);

exec dbms_stats.gather_table_stats(NULL,'TESTTBL');

-- 先ほどと同じSELECT文を実行

set autotrace on

set timing on

-- キャッシュの影響を排除するため、データベースバッファキャッシュをflush

alter system flush buffer_cache;

-- 実行計画とphysical reads をチェック

SELECT id, name FROM testtbl WHERE id = 1;

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 14

実行計画と物理I/Oブロック数の比較

-------------------------------------------------- | Id | Operation | Name | Rows |... | -------------------------------------------------- | 0 | SELECT STATEMENT | | 1 |... | |* 1 | TABLE ACCESS FULL| TESTTBL | 1 |... | -------------------------------------------------- 統計 ---------------------------------------------------------- 10098 physical reads

--------------------------------------------------------------------- | Id | Operation | Name | Rows |... | --------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 |... | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TESTTBL | 1 |... | |* 2 | INDEX RANGE SCAN | TESTIDX1 | 1 |... | --------------------------------------------------------------------- 統計 ---------------------------------------------------------- 3 physical reads

索引作成

(出力を整形しています)

(出力を整形しています)

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 15

[参考] SQL*Plusのautotrace

• 実行計画と実行統計を表示する

– 実行計画は 内部的にEXPLAIN PLAN +

DBMS_XPLAN.DISPLAYを用いて表示

– 問合せ結果表示のON/OFFも可能

• SQL> set autotrace [パラメータ]

パラメータ 実行計画 実行統計 問合せ結果

ON ○ ○ ○

ON EXPLAIN ○ ー ○

ON STATISTICS ー ○ ○

TRACEONLY ○ ○ ー

OFF ー ー ○

詳細は「SQL*Plusユーザーズ・ガイドおよびリファレンス」 → 「SQL*Plusのチューニング」、

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 16

適切な索引の作成

• どのような列に索引を作成するか

– SQLのWHERE句に頻繁に指定される列

– 結合(ジョイン)において、頻繁にキーに指定される列

– 参照整合性(外部キー)を設定した列

– そのほかの検討項目や、標準でない索引(ビットマップ索引など)については「パフォーマンス・チューニング・ガイド」の「索引およびクラスタの使用方法」を参照

• 索引の注意点

– データ更新時の負荷が増加する

• データと合わせて索引のメンテナンスが必要となるため

– 「索引を使ったアクセス = 最良のパフォーマンス」ではない場合もある

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 17

選択率と最適なアクセス

BLUE

BLUE

BLUE

BLUE

BLUE

BLUE

RED

BLUE

BLUE

BLUE

BLUE

BLUE

SELECT …

WHERE color='RED'

SELECT …

WHERE color ='BLUE'

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 18

デモ:偏りがある列を検索条件に指定

-- 1行だけ color='blue'に変更

update testtbl set color = 'blue' WHERE id = 1;

-- color列に索引を作成

create index testidx2 on testtbl(color);

exec dbms_stats.gather_table_stats(NULL,'TESTTBL');

-- データの偏りをチェック

set autotrace off

SELECT color, count(*) FROM testtbl GROUP BY color;

-- color='red'の行(29999行)をSELECT → TABLE ACCESS FULL + filter

set autotrace traceonly

-- color列に索引があるにもかかわらず、TABLE ACCESS FULL であることに着目

SELECT * FROM testtbl WHERE color='red';

-- こちらはINDEX RANGE SCAN

SELECT * FROM testtbl WHERE color='blue';

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 19

デモ:偏りがある列を検索条件に指定

-------------------------------------------------- | Id | Operation | Name | Rows |... | -------------------------------------------------- | 0 | SELECT STATEMENT | | 29999 |... | |* 1 | TABLE ACCESS FULL| TESTTBL | 29999 |... | -------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("COLOR"='red')

--------------------------------------------------------------------- | Id | Operation | Name | Rows |... | --------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 |... | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TESTTBL | 1 |... | |* 2 | INDEX RANGE SCAN | TESTIDX2 | 1 |... | --------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("COLOR"='blue')

検索ヒット行数= 29999行

検索ヒット行数= 1行

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 20

オプティマイザ統計の役割

• 最適な実行計画を作成するためには「データの格納状態」を知る必要がある

• オプティマイザ統計はデータの格納状態を集約した情報

• 「データの格納状態」が大きく変化した場合は、オプティマイザ統計を収集する

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 21

オプティマイザ統計の収集方法

• DBMS_STATS.GATHER_xxxx プロシージャを使用する

– 従来使用されていたANALYZEコマンドは使用しない

DBMS_STATSのプロシージャ 取得対象オブジェクト

GATHER_DATABASE_STATS データベース全体のオブジェクト

GATHER_SCHEMA_STATS 指定されたスキーマ内のオブジェクト

GATHER_TABLE_STATS 指定されたテーブル(+インデックス)

GATHER_INDEX_STATS 指定されたインデックス

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 22

オプティマイザ統計の注意点

• 大量データを更新するたびに、オプティマイザ統計を収集する必要がある

– DBMS_STATS.GATHER_xxxプロシージャを実行する

– データとオプティマイザ統計は独立

– 少量データ更新であれば、オプティマイザ統計を再収集する必要はない

• オプティマイザ統計はあくまでもデータの特徴を示す「サマリ情報」に過ぎないので、あまり神経質に再収集する必要はない

• Oracle Database 10g以降ではデフォルトで自動収集される

– 収集開始タイミング:平日22:00 + 土日

• バージョンにより詳細なスケジュールが異なることに注意

– 自動収集されるまでの間、データとオプティマイザ統計にズレが生じることに注意

• データ更新後にDBMS_STATS.GATHER_xxxプロシージャを実行すれば、ズレの発生を回避できる

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 23

Oracleアーキテクチャ – メモリ

セッション SGA

SQLの発行

実行結果の返送

データファイル

サーバープロセス

クライアント

アプリケーション

データベース

バッファ

キャッシュ

共有

プール

PGA

SQL実行

セッション

SQLの発行

実行結果の返送

サーバープロセス

クライアント

アプリケーション

PGA

SQL実行

専用サーバープロセス接続の場合

SGAの構成コンポーネントは省略して記載

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 24

データベースバッファキャッシュの役割

• データブロックのメモリキャッシュ

– 繰り返し同一のブロックにアクセスした場合の性能向上

• 論理I/Oと物理I/O

2回目のブロック読み出し

物理I/O

論理I/O

データファイル

SGA

データベース

バッファ

キャッシュ

1回目のブロック読み出し

データファイル

SGA

データベース

バッファ

キャッシュ

論理I/O

論理I/O=高速

物理I/O=低速

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 25

デモ:データベースバッファキャッシュの効果

-- 索引スキャンするSQLを2回実行して、キャッシュの効果をみる set autotrace traceonly alter system flush buffer_cache; -- 1回目の実行 SELECT * FROM testtbl WHERE id = 1; -- 2回目の実行 SELECT * FROM testtbl WHERE id = 1; -- physical reads がない → キャッシュされている -- consistent gets → 論理I/Oは実行されている

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 26

デモ: データベースバッファキャッシュの効果

--------------------------------------------------------------------- | Id | Operation | Name | Rows |... | --------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 |... | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TESTTBL | 1 |... | |* 2 | INDEX RANGE SCAN | TESTIDX1 | 1 |... | --------------------------------------------------------------------- 統計 ---------------------------------------------------------- : 4 consistent gets 3 physical reads

統計 ---------------------------------------------------------- : 4 consistent gets 0 physical reads

1回目の実行

2回目の実行

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 27

バッファヒット率

• Statspack / AWR レポートのInstance Efficiencyセクションから確認できる

– Statspack / AWR レポート: 性能分析用の診断レポート

• 最近のシステムでは99%程度も決して珍しくない

– SGAに割り当てられるメモリサイズが大きくなったため

Instance Efficiency Percentages (Target 100%) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Buffer Nowait %: 99.93 Redo NoWait %: 100.00 Buffer Hit %: 70.22 In-memory Sort %: 99.95 Library Hit %: 99.73 Soft Parse %: 98.99 Execute to Parse %: 74.86 Latch Hit %: 99.92 Parse CPU to Parse Elapsd %: 49.76 % Non-Parse CPU: 99.16 Shared Pool Statistics Begin End ------ ------ Memory Usage %: 72.48 70.71 % SQL with executions>1: 62.52 63.39 % Memory for SQL w/exec>1: 53.55 57.10

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 28

データベースバッファキャッシュの注意点

• (当然ながら)キャッシュできるブロック数には制限がある

– データベースバッファキャッシュ(or SGA)のメモリサイズに上限があるため

– いっぱいになったら、使用頻度が低いものから消去される (age-out)

• ダイレクトパスリードの場合はキャッシュされない

– PGAに直接データが読み込まれる

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 29

SQL解析と共有プール

• ハードパースで実施する処理

– SQL構文チェック

– アクセス対象オブジェクトのチェック

– SQLの最適化

– 実行計画の立案

• 解析結果は共有カーソルとして共有プールにキャッシュ

SGA サーバープロセス

クライアント

アプリケーション

共有プール

共有

カーソル

③キャッシュ

① SQL

解析

②ハードパース

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 30

共有カーソルのキャッシュ

• 一度実行されたSQLの解析結果(=共有カーソル)は再利用される

– ソフトパースによる処理効率化:SQL処理時間の短縮、CPU負荷の軽減

SGA サーバープロセス

解析

クライアント

アプリケーション

共有プール

共有

カーソル

③キャッシュ

サーバープロセス

クライアント

アプリケーション

②ハードパース

②ソフトパース

① SQL

① SQL

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 31

V$SQLと共有プール

• 共有プールにキャッシュされた共有カーソルに関する情報はV$SQLから確認できる

• 1つの共有カーソル(正確には子カーソル) = V$SQLの1行

主要な列名 確認できる情報

SQL_TEXT SQL文字列

SQL_ID SQLの識別子

EXECUTIONS 実行回数

CPU_TIME CPU使用時間

ELAPSED_TIME 所要時間

BUFFER_GETS バッファへのアクセス回数

DISK_READS ディスク読み取り数

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 32

デモ:V$SQLと共有プール

-- 同一のSQLを複数回実行して、共有カーソルのキャッシュ効果を見る

-- すでに共有カーソルが存在するとデモの意味がないので、いったん共有プールをflushする

set autotrace off

set timing off

ALTER SYSTEM flush shared_pool;

-- この時点では(実行しようとしているSQLの)共有カーソルは存在しない

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

-- SQLを実行して共有カーソルを確認

SELECT id, name FROM testtbl WHERE id = 1;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

-- SQLを再実行して共有カーソルが1つである(=再利用されている)ことを確認

-- executions列がカウントアップしていることも見る

SELECT id, name FROM testtbl WHERE id = 1;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 33

デモ:V$SQLと共有プール

-- 類似したSQLは別のSQLとして扱われる

SELECT id, name FROM testtbl WHERE id = 2;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

SELECT id, name FROM testtbl WHERE id = 1;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 34

WHERE条件のリテラル値のみが異なるSQL

• (類似していても)文字列として異なるSQLは、共有カーソルが共有されない

– ハードパースによる処理効率低下:SQL処理時間とCPU負荷増加

– 共有メモリの非効率的な利用:使用メモリ量増加、キャッシュヒット率低下

SGA サーバープロセス

解析

クライアント

アプリケーション

共有プール

共有

カーソル

③キャッシュ

サーバープロセス

クライアント

アプリケーション

②ハードパース

①SELECT …

WHERE id = 1

①SELECT …

WHERE id = 2

共有

カーソル

③キャッシュ

②ハードパース

解析

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 35

バインド変数による共有カーソルの再利用

• 一度実行されたSQLの解析結果は再利用される

– ソフトパースによる処理効率化:SQL処理時間の短縮、CPU負荷の軽減

– 共有メモリの効率的な利用:使用メモリ量削減、キャッシュヒット率向上

SGA サーバープロセス

解析

クライアント

アプリケーション

共有プール

共有

カーソル

③キャッシュ

サーバープロセス

クライアント

アプリケーション

②ハードパース

②ソフトパース

①SELECT …

WHERE id = :n

①SELECT …

WHERE id = :n

n=1

n=2

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 36

デモ:V$SQLから共有カーソルの動きを確認

-- リテラルを使用したSQLをバインド変数化して、共有カーソルのキャッシュ効果を見る

-- すでに共有カーソルが存在するとデモの意味がないので、いったん共有プールをflushする

ALTER SYSTEM flush shared_pool;

-- リテラルSQLでは、SQL毎に共有カーソルが作成される

SELECT id, name FROM testtbl WHERE id = 1;

SELECT id, name FROM testtbl WHERE id = 2;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

-- SQLをバインド変数化

variable n NUMBER

exec :n := 1

SELECT id, name FROM testtbl WHERE id = :n;

/* dummy */ SELECT sql_id,child_number, executions, sql_text FROM V$SQL WHERE sql_text LIKE 'SELECT%FROM testtbl%';

-- バインド変数値を変えて再実行 → 共有カーソルが再利用される

exec :n := 2

SELECT id, name FROM testtbl WHERE id = :n;

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 37

データのソート

SGA

一時ファイル

サーバープロセス

クライアント

アプリケーション

データベース

バッファ

キャッシュ

PGA

SQL実行

データファイル

1

2

3

4

1

2

3

4

セッション

SQLの発行

実行結果の返送

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 38

どのような時にソートが実行されるか

• どのような時にソートが実行されるか

– SELECT .. ORDER BY句

– ソートマージジョイン

– DISTINCT, UNIONなど重複排除系処理

• 最近のバージョンではハッシュに置き換えられている

– CREATE INDEX

– オプティマイザ統計の収集

– など

• ソートの負荷は高い

– 要件的に必要なければソートしない

– ソートが避けられない場合は、全量データが必要か検討する

• rownum疑似列を用いたデータ量の絞込み など

• ソート以外のデータ処理 : ハッシュ、ビットマップ

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 39

pga_aggregate_target

• 各プロセスのPGAの総サイズを制限

• おおむねpga_aggregate_targetの5%が各プロセスのPGAの上限値となる

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 40

デモ:ソート

-- ORDER BYを指定した時の実行計画と使用した作業領域を確認

-- pga_aggregate_target を小さい値に

alter system set memory_target = 0;

alter system set pga_aggregate_target = 100M scope=memory;

set autotrace traceonly

set timing on

-- sorts (disk) から一時表領域を使用してソートされていることがわかる

SELECT * FROM TESTTBL ORDER BY n;

-- pga_aggregate_target を大きい値に

alter system set pga_aggregate_target = 400M scope=memory;

-- sorts (memory) からPGAを使用してソートされていることがわかる

SELECT * FROM TESTTBL ORDER BY n;

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 41

デモ: ソート

--------------------------------------------------- | Id | Operation | Name | Rows |... | --------------------------------------------------- | 0 | SELECT STATEMENT | | 30000 |... | | 1 | SORT ORDER BY | | 30000 |... | | 2 | TABLE ACCESS FULL| TESTTBL | 30000 |... | --------------------------------------------------- 統計 ---------------------------------------------------------- : 0 sorts (memory) 1 sorts (disk)

統計 ---------------------------------------------------------- : 1 sorts (memory) 0 sorts (disk)

pga_aggregate_target = 400M

pga_aggregate_target = 100M

Copyright (C) 2015 CO-Sol Inc. All Rights Reserved 42

まとめ

• SQL処理においてOracleの構成要素がどのように関係するかを理解しましょう

• 索引を適切に使うことで、ファイルI/Oを削減できます

• 適切な実行計画作成にはオプティマイザ統計を適切に取得することが必要です

• SQL処理の性能向上に寄与する各種メモリ領域(データベースバッファキャッシュ、共有プール、PGA)の役割を理解しましょう

• ハードパースを回避するにはSQLのバインド変数化が有効なケースがあります