20120721 tuning slide_share
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

20120721 tuning slide_share

  • 1,622 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,622
On Slideshare
1,146
From Embeds
476
Number of Embeds
5

Actions

Shares
Downloads
8
Comments
0
Likes
0

Embeds 476

http://mutatsu.blog.fc2.com 398
http://admin.blog.fc2.com 70
http://www.feedspot.com 6
https://si0.twimg.com 1
http://feedly.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. こんなSQL性能改善策もあります ~ Oracle Database 11g バーチャル・カラム 活用 ~JPOUG 「JPOUG> SET EVENTS 20120721」アンカンファレンス資料宇多津 真彦2012年07月21日
  • 2. • 本資料はあくまで個人の見解に基づいて記述したもので あり、所属する会社・団体とは一切関係ありません。 2
  • 3. はじめに• 今日お話する内容は、ある特定の状況でしか使えない SQL性能改善であり、かつ、標題に「バーチャル・カラム」 とあるように、テーブルのカラム構造の変更まで視野に いれた話ですが、工夫次第でおもしろいことができる、 ということをお話します• Oracle Database 11gの基本機能に関する話ですが、 これを機会にいろんな機能に興味をもっていただけると 嬉しいです • まずは、「新機能マニュアル」を熟読ください 3
  • 4. お客様のある悩み 「SQLの処理で遅いものがある」 相談内容 • 受注表から請求対象データを抽出する処理お客様 • 受注表(履歴を持つ) → データ件数が多い 想定できること • 請求対象データを抽出 → 過去データの大半は請求済 (二重請求なし) • 「パーティショニングしてますか?」 お客様への質問 • 「請求対象は日付である程度区切れますか? もし区切れるとするならば、期間はどれくらいになりますか?」 • 「請求済みをフラグで管理していますか?」 4
  • 5. お客様からの状況説明 回答内容 「パーティションは使ってるよ」 「未請求データは受注テーブルのほんの一部なんだけど、 過去データを全件みにいってるみたいなんだよね」お客様 「うち(お客様企業)が扱っているのは日用品じゃないから、 受注から請求までの期間が長いんだよ。だから日付で 区切れないんだよね」 「請求対象は請求日が入ってないもの、かな」 • 日付で区切れなければパーティションも効果が得られない • IS NULL検索では対象データが少なくても索引は使われ ないので全件検索になってしまう 5
  • 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. 「未請求フラグ」カラムを追加する?• 「未請求フラグ」カラム追加懸念点 • 「受注表」に「未請求フラグ」カラムを追加。当カラムに索引作成 • 物理的に領域を使用(表、索引ともに) • 問題となっているSQL以外のアプリケーションに変更が発生 • 「請求日」カラムに日付がセットされると、「未請求フラグ」カラム を請求を示す値(0などに)更新する処理を追加 • アップデート・トリガーで更新? • 行儀の悪いSQLの修正 *の使用 SELECT * FROM 受注表 .. INSERT INTO 受注表 VALUES (:id, :dt .. カラム指定なし 7
  • 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. テストを実施してみる(その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. テストを実施してみる(その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. テストを実施してみる(その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. テストを実施してみる(その4) SQL*Plusのset autotraceの表示(1)(2) ヒストグラム未取得 ヒントで索引指定 ヒストグラム取得 ヒント指定無し(3) 12
  • 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. もう少し複雑なバーチャル・カラム(その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. パーティショニング+遅延セグメント作成との組合せを試してみる(その1)• 遅延セグメント作成機能 • Oracle Database 11g R2からのEnterprise Edition機能 • パーティショニングとの組合せは11.2.0.2以降より可能 • Oracle Database 11g R1より提供している時間隔パーティション (インターバル・パーティション)が使えない場合でも利用可能 例)参照パーティション(リファレンス・パーティション) パーティション・キーがDATE型、NUMBER型以外 • あらかじめ、想定されるパーティションを作成しておいてもよい 例) 25年分のパーティションをあらかじめ作成しておく、など 15
  • 16. パーティショニング+遅延セグメント作成との組合せを試してみる(その2) データ・ローディング 対象 初期エクステントは 確保される 16
  • 17. まとめ• Oracle Database 11g からの基本機能「バーチャル・カラム」 を利用した性能改善案についてお話しました• また、パーティショニングと遅延セグメント作成(EE機能)の 組合せについてもご紹介しました• 新しいバージョンの新機能をいろんなところに適用して みてください • 古いバージョンを使っているところは早々にバージョンアップを ご検討ください! 17