- - PR -
9iと10gの処理時間の差について
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-05-23 16:03
こんにちは。いつも勉強させていただいています。
とあるSELECT文を発行した際、社内の同じネットワーク上に接続されている Oracleの9iと10gで処理時間に差が出ました。 9iでは瞬時に処理が行われるのに対し10gでは数秒かかります。 理由がSELECT文の書き方にあるとしたらと後学のためにご教示頂ければと書 き込みさせていただきました。 環境は、Oracle Database 9iと10g アプリケーションはVB6で作成(oo4o)しています。 CreateDynaset()でSELECT文を発行するものです。 問題のSELECT文は下記の稚拙なものです(すみません)。 YMDはインデックスです。 NAME、BUNRUI1、BUNRUI2はすべてCHARでNOT NULLです。 SELECT S11.CNT SCNT11, S12.CNT SCNT12, S13.CNT SCNT13, S14.CNT SCNT14, S15.CNT SCNT15, S16.CNT SCNT16, S17.CNT SCNT17 FROM (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '01') S11, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '02') S12, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '03') S13, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '04') S14, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '05') S15, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '06') S16, (SELECT COUNT(NAME) CNT FROM TBL WHERE ( YMD >= '20060101' AND YMD <= '20061231' ) AND BUNRUI1 = '01' AND BUNRUI2 = '07') S17 データとしては9iも10gも全く同じデータです。 よろしくお願い致します。 | ||||
|
投稿日時: 2007-05-23 16:29
サーバースペックは同等なんですよね?
その程度のSQLでしたらSELECT文の書き方を疑うより、キャッシュやオプティマイザーに注目した方が早いかも。 | ||||
|
投稿日時: 2007-05-23 17:43
レスありがとうございます。
>サーバースペックは同等なんですよね? 9iがPENV1.2G 10gがPEN4 3G(DUAL) だったりします。 >その程度のSQLでしたらSELECT文の書き方を疑うより、キャッシュやオプティマイザーに注目した方が早いかも。 キャッシュですか。。。 正直その方面明るくはないのですが、大変ありがたく手がかりにさせて頂きます。 | ||||
|
投稿日時: 2007-05-23 23:42
同じSQLを2回実行してそれぞれの時間を計る。これを2つのサーバーでやってみると何か面白い結果がでるかも? やはり差が出るようでしたら、全件対象で同じことをやってみる。 SELECT COUNT(NAME) CNT FROM TBL これでも同様ならSQLの問題じゃないですよね? ここで逆転するならインデックスを使って同じことをやってみる。 SELECT COUNT(NAME) CNT FROM TBL WHERE YMD >= '20060101' AND YMD <= '20061231' 案外 SELECT SYSDATE FROM DUAL でも同等の差が出たりして(笑) | ||||
|
投稿日時: 2007-05-24 14:36
ラフィンさん、レスありがとうございます。
> 同じSQLを2回実行してそれぞれの時間を計る。これを2つのサーバーでやってみると何か面白い結果がでるかも? >(以下略させて頂きました) 試してみました。 CreateDynaset()でSELECT文を発行したまま返答がない状態になります。 うーむ。。。 | ||||
|
投稿日時: 2007-05-24 14:56
バインド変数も使って無さそうな SQL なので、 SQL*Plus から実行して
SQL トレースを取れないか、とおもいますがどうでしょう。 (単なる SQL_TRACE = true より event 10046 level 8 で採取した方がいい) せっかく索引があるのに、データが同じでも統計情報が実情にあって無くて 全件検索しまくってるとか。 # ただ、YMD のデータ型が不明ですが DATE 型だったら # 暗黙変換しまくりそうな書き方ですね。 _________________ もしもし@RMAN 友の会 | ||||
|
投稿日時: 2007-05-25 10:28
>もしもしさん
なるほど、こういうのがあったんですね。勉強になりました。 私は alter session set sql_trace=true; alter session set timed_statistics=true; set autotrace on; の3本セットから tkprof をやっていました。 実行プランの確認だけならツールで行いますけど。 >隣の古柴さん SQLがそれでいいのかははなはだ疑問ですが、実際に何が起こっているのかを調べることが大切かと思います。ハード環境、Oracleのバージョンや設定、テーブルの構造やデータ、全てが同じであっても同じSQLに対してDBMSが同じ挙動をするとは限りません。 | ||||
|
投稿日時: 2007-05-25 10:39
event 10046 の説明はここにあります。実行計画だけじゃなくて待機イベントも確認できるので、大抵は level 8 で取ってます。
_________________ もしもし@RMAN 友の会 [ メッセージ編集済み 編集者: もしもし 編集日時 2007-05-25 10:40 ] |