Contenu connexe
Similaire à 20120721 tuning slide_share
Similaire à 20120721 tuning slide_share (20)
20120721 tuning slide_share
- 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
- 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
- 17. まとめ
• Oracle Database 11g からの基本機能「バーチャル・カラム」
を利用した性能改善案についてお話しました
• また、パーティショニングと遅延セグメント作成(EE機能)の
組合せについてもご紹介しました
• 新しいバージョンの新機能をいろんなところに適用して
みてください
• 古いバージョンを使っているところは早々にバージョンアップを
ご検討ください!
17