0
こんなSQL性能改善策もあります ~ Oracle Database 11g バーチャル・カラム 活用 ~JPOUG 「JPOUG> SET EVENTS 20120721」アンカンファレンス資料宇多津 真彦2012年07月21日
• 本資料はあくまで個人の見解に基づいて記述したもので  あり、所属する会社・団体とは一切関係ありません。                              2
はじめに• 今日お話する内容は、ある特定の状況でしか使えない  SQL性能改善であり、かつ、標題に「バーチャル・カラム」  とあるように、テーブルのカラム構造の変更まで視野に  いれた話ですが、工夫次第でおもしろいことができる、  ということを...
お客様のある悩み      「SQLの処理で遅いものがある」        相談内容      • 受注表から請求対象データを抽出する処理お客様  • 受注表(履歴を持つ) → データ件数が多い    想定できること  • 請求対象データを抽出...
お客様からの状況説明                              回答内容      「パーティションは使ってるよ」      「未請求データは受注テーブルのほんの一部なんだけど、       過去データを全件みにいってるみたいな...
想定されるSQLの処理• パーティショニングが効果的な問い合わせ  SELECT * FROM 受注表             パーティション・キー  WHERE 受注日 >= TO_DATE(2012/07/01,YYYY/MM/DD)   ...
「未請求フラグ」カラムを追加する?• 「未請求フラグ」カラム追加懸念点 • 「受注表」に「未請求フラグ」カラムを追加。当カラムに索引作成    • 物理的に領域を使用(表、索引ともに) • 問題となっているSQL以外のアプリケーションに変更が発...
バーチャル・カラム機能を使ってみる• Oracle Database 11gからの標準機能• 実データは持たず、他のカラムから関数によって定義される  仮想的な列 • ディスク上に格納されない列 • 他のカラムから導出されるカラムの為、更新でき...
テストを実施してみる(その1)• テストデータ: 180万行(1,000件/日 × 30日×12月×5年) • うち、1ヶ月分(30,000行)を抽出対象とする(1/60)• 1行あたり500Byte • 500Byte × 1,800,000...
テストを実施してみる(その2)• テストデータ投入後、バーチャル・カラム作成 ALTER TABLE test01 ADD (      vflg01   VARCHAR2(1) AS (DECODE(dt02,NULL,1,0)),     ...
テストを実施してみる(その3) • セグメントのサイズ比較 • アクセスパス比較      • 以下の3種類で比較(次ページ以降)(1)   SELECT MAX(dt01) FROM test01 WHERE dt02 IS NULL;(2)...
テストを実施してみる(その4)  SQL*Plusのset autotraceの表示(1)(2)                           ヒストグラム未取得                               ヒントで索引指...
もう少し複雑なバーチャル・カラム(その1)• 抽出条件を追加 • 「出荷日」に日付がセットされていて、   かつ「請求日」に日付がセットされていない  SELECT * FROM 受注表      WHERE 出荷日 IS NOT NULL  ...
もう少し複雑なバーチャル・カラム(その2)• 実装イメージ CREATE TABLE test02 (                                         ALTER TABLE test02 ADD (   id ...
パーティショニング+遅延セグメント作成との組合せを試してみる(その1)• 遅延セグメント作成機能 • Oracle Database 11g R2からのEnterprise Edition機能    • パーティショニングとの組合せは11.2....
パーティショニング+遅延セグメント作成との組合せを試してみる(その2)                   データ・ローディング                       対象      初期エクステントは        確保される     ...
まとめ• Oracle Database 11g からの基本機能「バーチャル・カラム」  を利用した性能改善案についてお話しました• また、パーティショニングと遅延セグメント作成(EE機能)の  組合せについてもご紹介しました• 新しいバージョ...
Upcoming SlideShare
Loading in...5
×

20120721 tuning slide_share

1,646

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,646
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "20120721 tuning slide_share"

  1. 1. こんなSQL性能改善策もあります ~ Oracle Database 11g バーチャル・カラム 活用 ~JPOUG 「JPOUG> SET EVENTS 20120721」アンカンファレンス資料宇多津 真彦2012年07月21日
  2. 2. • 本資料はあくまで個人の見解に基づいて記述したもので あり、所属する会社・団体とは一切関係ありません。 2
  3. 3. はじめに• 今日お話する内容は、ある特定の状況でしか使えない SQL性能改善であり、かつ、標題に「バーチャル・カラム」 とあるように、テーブルのカラム構造の変更まで視野に いれた話ですが、工夫次第でおもしろいことができる、 ということをお話します• Oracle Database 11gの基本機能に関する話ですが、 これを機会にいろんな機能に興味をもっていただけると 嬉しいです • まずは、「新機能マニュアル」を熟読ください 3
  4. 4. お客様のある悩み 「SQLの処理で遅いものがある」 相談内容 • 受注表から請求対象データを抽出する処理お客様 • 受注表(履歴を持つ) → データ件数が多い 想定できること • 請求対象データを抽出 → 過去データの大半は請求済 (二重請求なし) • 「パーティショニングしてますか?」 お客様への質問 • 「請求対象は日付である程度区切れますか? もし区切れるとするならば、期間はどれくらいになりますか?」 • 「請求済みをフラグで管理していますか?」 4
  5. 5. お客様からの状況説明 回答内容 「パーティションは使ってるよ」 「未請求データは受注テーブルのほんの一部なんだけど、 過去データを全件みにいってるみたいなんだよね」お客様 「うち(お客様企業)が扱っているのは日用品じゃないから、 受注から請求までの期間が長いんだよ。だから日付で 区切れないんだよね」 「請求対象は請求日が入ってないもの、かな」 • 日付で区切れなければパーティションも効果が得られない • IS NULL検索では対象データが少なくても索引は使われ ないので全件検索になってしまう 5
  6. 6. 想定されるSQLの処理• パーティショニングが効果的な問い合わせ SELECT * FROM 受注表 パーティション・キー WHERE 受注日 >= TO_DATE(2012/07/01,YYYY/MM/DD) AND 受注日 < TO_DATE(2012/07/31,YYYY/MM/DD)+1 AND 請求日 IS NULL ; -- 未請求 IS NULL検索でも、 パーティションで十分に 絞り込みができれば 問題なし• 「受注日」カラムで条件指定できなければ、「未請求フラグ」 カラムを追加してデータを絞り込むしかない • 幸い、大半のデータは請求済み • 「未請求フラグ」に索引を作成すれば効果的にデータ絞り込みができる SELECT * FROM 受注表 WHERE 未請求フラグ = 1 ; -- 未請求 6
  7. 7. 「未請求フラグ」カラムを追加する?• 「未請求フラグ」カラム追加懸念点 • 「受注表」に「未請求フラグ」カラムを追加。当カラムに索引作成 • 物理的に領域を使用(表、索引ともに) • 問題となっているSQL以外のアプリケーションに変更が発生 • 「請求日」カラムに日付がセットされると、「未請求フラグ」カラム を請求を示す値(0などに)更新する処理を追加 • アップデート・トリガーで更新? • 行儀の悪いSQLの修正 *の使用 SELECT * FROM 受注表 .. INSERT INTO 受注表 VALUES (:id, :dt .. カラム指定なし 7
  8. 8. バーチャル・カラム機能を使ってみる• Oracle Database 11gからの標準機能• 実データは持たず、他のカラムから関数によって定義される 仮想的な列 • ディスク上に格納されない列 • 他のカラムから導出されるカラムの為、更新できない • 索引付けが可能であり、統計を収集できる 索引作成• 「受注表」にバーチャル・カラムを適用したイメージ id 受注日 請求日 未請求フラグ 1 2012/06/21 2012/07/21 NULL 2 2012/06/21 2012/07/21 NULL 検索対象外の値を NULLにすることで 3 2012/07/21 NULL 1 索引のサイズを 小さくできます 4 2012/07/21 NULL 1 バーチャル・カラム作成 8
  9. 9. テストを実施してみる(その1)• テストデータ: 180万行(1,000件/日 × 30日×12月×5年) • うち、1ヶ月分(30,000行)を抽出対象とする(1/60)• 1行あたり500Byte • 500Byte × 1,800,000 = 900,000,000 なので、1GB程度のデータ量• カラム構成 CREATE TABLE test01 ( id NUMBER(8) CONSTRAINT PK_test01 PRIMARY KEY, dt01 DATE, -- 受注日相当 dt02 DATE, -- 請求日相当 まずは非パーティション表で確認 dummy CHAR(482) )TABLESPACE test; extent 5MB単位 9
  10. 10. テストを実施してみる(その2)• テストデータ投入後、バーチャル・カラム作成 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 10
  11. 11. テストを実施してみる(その3) • セグメントのサイズ比較 • アクセスパス比較 • 以下の3種類で比較(次ページ以降)(1) SELECT MAX(dt01) FROM test01 WHERE dt02 IS NULL;(2) SELECT MAX(dt01) FROM test01 WHERE vflg01 = 1;(3) SELECT MAX(dt01) FROM test01 WHERE vflg02 = 1; 11
  12. 12. テストを実施してみる(その4) SQL*Plusのset autotraceの表示(1)(2) ヒストグラム未取得 ヒントで索引指定 ヒストグラム取得 ヒント指定無し(3) 12
  13. 13. もう少し複雑なバーチャル・カラム(その1)• 抽出条件を追加 • 「出荷日」に日付がセットされていて、 かつ「請求日」に日付がセットされていない 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 NULLにすることで 索引のサイズを 4 2012/07/21 NULL NULL NULL 小さくできます バーチャル・カラム作成 13
  14. 14. もう少し複雑なバーチャル・カラム(その2)• 実装イメージ CREATE TABLE test02 ( ALTER TABLE test02 ADD ( id NUMBER(8) vflg01 VARCHAR2(1) AS ( CONSTRAINT PK_test02 PRIMARY KEY, DECODE(dt02,NULL,NULL, dt01 DATE, -- 受注日相当 DECODE(dt03,NULL,1,NULL) dt02 DATE, -- 出荷日相当 ) dt03 DATE, -- 請求日相当 ) dummy CHAR(475) ); )TABLESPACE test; SELECT MAX(dt01) FROM test02 WHERE DT02 IS NOT NULL AND DT03 IS NULL; SELECT MAX(dt01) 検索対象 FROM test02 WHERE vflg01 = 1; 14
  15. 15. パーティショニング+遅延セグメント作成との組合せを試してみる(その1)• 遅延セグメント作成機能 • Oracle Database 11g R2からのEnterprise Edition機能 • パーティショニングとの組合せは11.2.0.2以降より可能 • Oracle Database 11g R1より提供している時間隔パーティション (インターバル・パーティション)が使えない場合でも利用可能 例)参照パーティション(リファレンス・パーティション) パーティション・キーがDATE型、NUMBER型以外 • あらかじめ、想定されるパーティションを作成しておいてもよい 例) 25年分のパーティションをあらかじめ作成しておく、など 15
  16. 16. パーティショニング+遅延セグメント作成との組合せを試してみる(その2) データ・ローディング 対象 初期エクステントは 確保される 16
  17. 17. まとめ• Oracle Database 11g からの基本機能「バーチャル・カラム」 を利用した性能改善案についてお話しました• また、パーティショニングと遅延セグメント作成(EE機能)の 組合せについてもご紹介しました• 新しいバージョンの新機能をいろんなところに適用して みてください • 古いバージョンを使っているところは早々にバージョンアップを ご検討ください! 17
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×