- PR -

Oracle10g(WindowsXP)のチューニング方法

1
投稿者投稿内容
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2007-05-09 18:04
いつもお世話になっております。

Oracleのチューニングについて調べているのですが、
思ったような成果が得られません。

Oracle10g(WindowsXP)のチューニング方法について教えて下さい。
(SQLチューニングではなく、Oracle設定変更によるチューニングです。)

設定値を確認したところ、下記のようになっていました。

show parameters sga_max_size; 164M
show parameters sga_target; 0
show parameters db_cache_size; 24M
show parameters shared_pool_size; 80M
show parameters large_pool_size; 8M
show parameters java_pool_size; 48M

そこで、Oracleの自動調整機能を利用して、
パフォーマンス向上を望めないかと思い下記を実行しました。

alter system set sga_target=164M;
alter system set db_cache_size=0M;
alter system set shared_pool_size=0M;
alter system set large_pool_size=0;
alter system set java_pool_size=0;

※alter system set db_cache_size=0M;は、エラーが出ました。

上記後のアプリの動作としては、何も変化せず遅いままでした。

また、sga_max_sizeの値を大きくできれば、ヒット率も向上して
処理速度が向上するのでは?と考えているのですが、変更する方法がわかりません。
(的外れでしょうか?)

何か他に良いチューニング案はないものでしょうか?
またOracle初心者なので、参考になるサイトなどありましたら教えて下さい。

環境は、下記です。
 OS   :WinXP(SP2)
 DB   :Oracle10g Personal
 開発環境:VS2005(VC++)でoo4oを使用

以上、長々と書いてしまいましたが的外れな質問の可能性もありますが、
よろしくお願いいたします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-05-09 19:15
引用:

Makotoさんの書き込み (2007-05-09 18:04) より:
また、sga_max_sizeの値を大きくできれば、ヒット率も向上して
処理速度が向上するのでは?と考えているのですが、変更する方法がわかりません。
(的外れでしょうか?)


こんなのはどうですか?
http://www.oracle.co.jp/grid/papers/db/SMMemory.pdf

引用:

何か他に良いチューニング案はないものでしょうか?
またOracle初心者なので、参考になるサイトなどありましたら教えて下さい。


db_cache_sizeやshared_pool_sizeによるチューニングはほぼ最終手段です。
元の設定値があまりにひどい場合は効果がある場合もありますが、
その前にやるべきもっと効果の大きい手法がたくさんあります。

「遅い」のはどこなのか特定されていますか?
そして、それがなぜ「遅い」のか特定されていますか?

全てのクエリが遅いのですか?普通は一部のクエリが遅いはずです。
遅いクエリさえ特定できれば、実行計画からなぜ遅いのか特定できます。

クエリ実行回数が多すぎて、通信オーバーヘッドにより遅いのかもしれません。
このような場合はストアドプロシージャに纏めると大きな性能向上を見込めます。

一部に極端に遅いクエリがあったとすると、
多くの場合は巨大なテーブルのフルスキャンや、
巨大なテーブル同士のnested loop joinが行われているのでしょう。
(単純にフルスキャンやnested loop joinは悪、というわけではありません)

この場合は、必要なインデックスがなかったり、古い統計情報で実行計画を
立てたために適切なインデックスが使われていない場合が多いと思います。

条件によってはフルスキャンを回避するために、
パーティション化しないといけない場合もあるかもしれません。

さらに、大きなテーブルの不要なフルスキャンは
バッファキャッシュのヒット率を下げてしまう結果にもなるため、
この状態でdb_cache_sizeを調整しても無意味になってしまいます。

とりあえず、ここに挙げたキーワードで検索するといろいろ見つかりますよ。

[訂正]
おおっと。large_pool_sizeじゃなくてshared_pool_sizeだ。
[/訂正]

[ メッセージ編集済み 編集者: あしゅ 編集日時 2007-05-09 19:27 ]
未記入
会議室デビュー日: 2006/03/22
投稿数: 19
投稿日時: 2007-05-09 21:38
既に指摘されている内容はクリアしているとして
もしアプリケーションコードを同一サーバー上で実行しているなら
ハードのスペックは十分ですか?
遅いという内容が抽象的でよくわからないので当てずっぽうですが
デフォルト設定でDB作成しているとしてメモリが1GB位とふんでいるのですが
処理内容に比べて明らかにメモリが少ないとかでは?
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2007-05-09 22:11
SGAや初期設定パラメータの変更は意味を理解してからやってください。
ゲームのキャラのパラメータ変更とは大違いです。

Statspacというのが、あってそれがあれば、資源を使うSQLを容易に見つけることができます。

http://otn.oracle.co.jp/skillup/stats_diag/index.html
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2007-05-10 08:57
早速の回答ありがとうございます。

遅いクエリの件ですが、場所はわかっています。

ただ遅いといっても、『4つのTBL(それぞれが1000レコード)から
1件を取り出す処理』を実行して、
アプリのメモリにマッピングするのに40ms程度です。(これは遅いでしょうか?)
正直『inner joinする』とか『viewを作る』とかの方が高速と思ってはいます。
正直なところ、直したいのですが、
直すと全体へのインパクトが大きすぎて直せないというのが現状です。

おそらくは、あしゅ様に指摘して頂いた下記がこれにあたると考えています。

 『クエリ実行回数が多すぎて、通信オーバーヘッドにより遅いのかもしれません。』

複数のTBLから関連するデータを1件づつforループで取得しているのですが、
40ms×1000件=40sになっています。
(件数に比例して遅くなるので間違いないと考えています。)

ただ、修正することが難しいので、『Oracle設定変更によるチューニング』で
どうにかできないかと考えてみました。

To:Tetra様

アプリケーションコードにも問題はあると踏んでいるのですが、
手を入れられる状況にないというのが現状です。
またご指摘のハードスペックは、『メモリ1G、CPUはCoreDuo』
で現時点で手配できるPCではほぼ最高スペックのものです。(ベンダWebサイトによる)
また、ハードスペック変更は難しい状況なのです。

To:七味唐辛子様

問題のSQL検出はできているのですが、
それをせずにどうにかできないものか?
ということで質問させていただいておりました。
『Statspac』は、一つ勉強になりました。

まとめると、やはりSQLチューニングせずにどうにかするという
むしのいい話はないということですね。

勉強になりました。教えていただいたサイトやソースコードもチェックしてみます。
また質問させていただくこともあると思いますが、よろしくお願いします。
ありがとうございました。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-05-10 09:29
引用:

Makotoさんの書き込み (2007-05-10 08:57) より:
複数のTBLから関連するデータを1件づつforループで取得しているのですが、
40ms×1000件=40sになっています。


通信オーバーヘッドはDB側でのチューニングは無意味です。
ネットワーク等を見直したところで効果はたかが知れています。

頑張ってアプリ側の設計を変えないと意味はないでしょう。
件数に比例してクエリ回数が増加する箇所はネックになりがちです。

解決策は、予め必要なレコード範囲がわかるのなら対象レコードを全件、
実際にデータを見ないとどのレコードが必要になるかわからない場合は、
判明したキーをFIFOキューにでも入れて、ある程度溜まったところで
適宜IN句で複数件まとめて検索する手法でしょうね。
KOX
大ベテラン
会議室デビュー日: 2004/08/23
投稿数: 142
投稿日時: 2007-05-10 11:32
あしゅさんもおっしゃっていますが、
40ms × 1000件を1つのSQLにできるように変更する必要がありそうですね。

IN句の制限で確か1000件までしか対応していない(9iの場合。10gは?)ので、
件数には注意が必要です。
ただしIN句に1000件程度入れると、おそらくfullscanになってしまって速度は期待できません。
IN句の中身は、サブクエリにしていないと難しいかと思います。

#1件取得するのに40msは遅いですね。これも1桁ぐらいにはならないと・・・

Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2007-05-10 17:53
To:あしゅ様、KOX様

いつもお世話になっております。

貴重なご意見ありがとうございます。
いろいろ勉強になり助かります。

その後、ソースと格闘していたのですが、
本現象発生時のデータは、実運用ではほぼ発生しないデータであること
がわかりました。
(データのレコード数ではなく、各レコードごとの設定データです。)

これがある設定値になっていると、先ほどからの問題の処理で
forループ内のクエリ発行回数が少なくなることがわかりました。
(これは、アプリの仕様としてです。)

結論としては、
 ・実運用で(ほぼ)ありえないデータで試験→遅い
 ・実運用でありえるデータで試験→早い(問題なし)
ということになります。

開発途中のため、テスト用としてDBデータをinsertしていましたため
発生していましたが、実運用で起きないのであれば良しということで
落ち着きそうです。

ただDB的な結論としては、やはりクエリ回数が大きな問題だった
ということは確実です。

結局DBではなくアプリ側で回避という形になりましたが、
いろいろ勉強になりました。ありがとうございました。
今後もよろしくお願いします。
1

スキルアップ/キャリアアップ(JOB@IT)