20120721 tuning slide_share

17
こんなSQL性能改善策もあります Oracle Database 11g バーチャル・カラム 活用 JPOUG JPOUG> SET EVENTS 20120721アンカンファレンス資料 宇多津 真彦 20120721

description

 

Transcript of 20120721 tuning slide_share

Page 1: 20120721 tuning slide_share

こんなSQL性能改善策もあります

~ Oracle Database 11g バーチャル・カラム 活用 ~

JPOUG 「JPOUG> SET EVENTS 20120721」 アンカンファレンス資料 宇多津 真彦 2012年07月21日

Page 2: 20120721 tuning slide_share

• 本資料はあくまで個人の見解に基づいて記述したものであり、所属する会社・団体とは一切関係ありません。

2

Page 3: 20120721 tuning slide_share

はじめに

• 今日お話する内容は、ある特定の状況でしか使えないSQL性能改善であり、かつ、標題に「バーチャル・カラム」とあるように、テーブルのカラム構造の変更まで視野に いれた話ですが、工夫次第でおもしろいことができる、 ということをお話します

• Oracle Database 11gの基本機能に関する話ですが、 これを機会にいろんな機能に興味をもっていただけると 嬉しいです • まずは、「新機能マニュアル」を熟読ください

3

Page 4: 20120721 tuning slide_share

お客様のある悩み

4

「SQLの処理で遅いものがある」

•受注表から請求対象データを抽出する処理 お客様

•受注表(履歴を持つ) → データ件数が多い

•請求対象データを抽出 → 過去データの大半は請求済 (二重請求なし)

•「パーティショニングしてますか?」

•「請求対象は日付である程度区切れますか? もし区切れるとするならば、期間はどれくらいになりますか?」

•「請求済みをフラグで管理していますか?」

想定できること

相談内容

お客様への質問

Page 5: 20120721 tuning slide_share

お客様からの状況説明

5

「パーティションは使ってるよ」

「未請求データは受注テーブルのほんの一部なんだけど、過去データを全件みにいってるみたいなんだよね」

「うち(お客様企業)が扱っているのは日用品じゃないから、受注から請求までの期間が長いんだよ。だから日付で区切れないんだよね」

「請求対象は請求日が入ってないもの、かな」

お客様

•日付で区切れなければパーティションも効果が得られない

• IS NULL検索では対象データが少なくても索引は使われ ないので全件検索になってしまう

回答内容

Page 6: 20120721 tuning slide_share

想定されるSQLの処理

• パーティショニングが効果的な問い合わせ

• 「受注日」カラムで条件指定できなければ、「未請求フラグ」 カラムを追加してデータを絞り込むしかない • 幸い、大半のデータは請求済み

• 「未請求フラグ」に索引を作成すれば効果的にデータ絞り込みができる

6

SELECT * FROM 受注表

WHERE 受注日 >= TO_DATE('2012/07/01','YYYY/MM/DD')

AND 受注日 < TO_DATE('2012/07/31','YYYY/MM/DD')+1

AND 請求日 IS NULL ; -- 未請求

SELECT * FROM 受注表

WHERE 未請求フラグ = '1' ; -- 未請求

パーティション・キー

IS NULL検索でも、 パーティションで十分に

絞り込みができれば 問題なし

Page 7: 20120721 tuning slide_share

「未請求フラグ」カラムを追加する?

• 「未請求フラグ」カラム追加懸念点 • 「受注表」に「未請求フラグ」カラムを追加。当カラムに索引作成

• 物理的に領域を使用(表、索引ともに)

• 問題となっているSQL以外のアプリケーションに変更が発生

• 「請求日」カラムに日付がセットされると、「未請求フラグ」カラム を請求を示す値('0'などに)更新する処理を追加

• アップデート・トリガーで更新?

• 行儀の悪いSQLの修正

7

SELECT * FROM 受注表 ..

INSERT INTO 受注表 VALUES (:id, :dt ..

*の使用

カラム指定なし

Page 8: 20120721 tuning slide_share

バーチャル・カラム機能を使ってみる

• Oracle Database 11gからの標準機能

• 実データは持たず、他のカラムから関数によって定義される仮想的な列 • ディスク上に格納されない列

• 他のカラムから導出されるカラムの為、更新できない

• 索引付けが可能であり、統計を収集できる

• 「受注表」にバーチャル・カラムを適用したイメージ

8

id 受注日 請求日 未請求フラグ

1 2012/06/21 2012/07/21 NULL

2 2012/06/21 2012/07/21 NULL

3 2012/07/21 NULL '1'

4 2012/07/21 NULL '1'

バーチャル・カラム作成

索引作成

検索対象外の値を NULLにすることで 索引のサイズを 小さくできます

Page 9: 20120721 tuning slide_share

テストを実施してみる(その1)

• テストデータ: 180万行(1,000件/日 × 30日×12月×5年) • うち、1ヶ月分(30,000行)を抽出対象とする(1/60)

• 1行あたり500Byte • 500Byte × 1,800,000 = 900,000,000 なので、1GB程度のデータ量

• カラム構成

9

CREATE TABLE test01 (

id NUMBER(8) CONSTRAINT PK_test01 PRIMARY KEY,

dt01 DATE, -- 受注日相当

dt02 DATE, -- 請求日相当

dummy CHAR(482)

)TABLESPACE test;

まずは非パーティション表で確認

extent 5MB単位

Page 10: 20120721 tuning slide_share

テストを実施してみる(その2)

• テストデータ投入後、バーチャル・カラム作成

• 索引作成

• テストデータ確認

10

ALTER TABLE test01 ADD (

vflg01 VARCHAR2(1) AS (DECODE(dt02,NULL,'1','0')),

vflg02 VARCHAR2(1) AS (DECODE(dt02,NULL,'1',NULL))

);

CREATE INDEX test01_vflg01 ON test01(vflg01)TABLESPACE users;

CREATE INDEX test01_vflg02 ON test01(vflg02)TABLESPACE users;

索引のサイズ比較

extent 64KB単位

NULL

Page 11: 20120721 tuning slide_share

テストを実施してみる(その3)

• セグメントのサイズ比較

• アクセスパス比較 • 以下の3種類で比較(次ページ以降)

11

SELECT MAX(dt01) FROM test01 WHERE dt02 IS NULL;

SELECT MAX(dt01) FROM test01 WHERE vflg01 = '1';

SELECT MAX(dt01) FROM test01 WHERE vflg02 = '1';

(1)

(2)

(3)

Page 12: 20120721 tuning slide_share

テストを実施してみる(その4) SQL*Plusのset autotraceの表示

(1)

(2)

(3)

12

ヒストグラム未取得 ヒントで索引指定

ヒストグラム取得 ヒント指定無し

Page 13: 20120721 tuning slide_share

もう少し複雑なバーチャル・カラム(その1)

• 抽出条件を追加 • 「出荷日」に日付がセットされていて、

かつ「請求日」に日付がセットされていない

• 「受注表」にバーチャル・カラムを適用したイメージ

13

SELECT * FROM 受注表

WHERE 出荷日 IS NOT NULL

AND 請求日 IS NULL ; -- 未請求

id 受注日 出荷日 請求日 請求対象フラグ

1 2012/06/21 2012/07/05 2012/07/21 NULL

2 2012/06/21 2012/07/05 2012/07/21 NULL

3 2012/07/21 2012/07/21 NULL '1'

4 2012/07/21 NULL NULL NULL

バーチャル・カラム作成

索引作成

検索対象外の値を NULLにすることで 索引のサイズを 小さくできます

Page 14: 20120721 tuning slide_share

もう少し複雑なバーチャル・カラム(その2)

• 実装イメージ

14

CREATE TABLE test02 (

id NUMBER(8)

CONSTRAINT PK_test02 PRIMARY KEY,

dt01 DATE, -- 受注日相当

dt02 DATE, -- 出荷日相当

dt03 DATE, -- 請求日相当

dummy CHAR(475)

)TABLESPACE test;

ALTER TABLE test02 ADD (

vflg01 VARCHAR2(1) AS (

DECODE(dt02,NULL,NULL,

DECODE(dt03,NULL,'1',NULL)

)

)

);

SELECT MAX(dt01)

FROM test02

WHERE DT02 IS NOT NULL

AND DT03 IS NULL;

SELECT MAX(dt01)

FROM test02

WHERE vflg01 = '1';

検索対象

Page 15: 20120721 tuning slide_share

パーティショニング+遅延セグメント作成との 組合せを試してみる(その1)

• 遅延セグメント作成機能 • Oracle Database 11g R2からのEnterprise Edition機能

• パーティショニングとの組合せは11.2.0.2以降より可能

• Oracle Database 11g R1より提供している時間隔パーティション (インターバル・パーティション)が使えない場合でも利用可能

例)参照パーティション(リファレンス・パーティション) パーティション・キーがDATE型、NUMBER型以外

• あらかじめ、想定されるパーティションを作成しておいてもよい

例) 25年分のパーティションをあらかじめ作成しておく、など

15

Page 16: 20120721 tuning slide_share

パーティショニング+遅延セグメント作成との 組合せを試してみる(その2)

16

データ・ローディング 対象

初期エクステントは 確保される

Page 17: 20120721 tuning slide_share

まとめ

• Oracle Database 11g からの基本機能「バーチャル・カラム」を利用した性能改善案についてお話しました

• また、パーティショニングと遅延セグメント作成(EE機能)の組合せについてもご紹介しました

• 新しいバージョンの新機能をいろんなところに適用して みてください • 古いバージョンを使っているところは早々にバージョンアップを

ご検討ください!

17