PL SQL のループでセレクト文のパフォーマンスを測定する方法

このQ&Aのポイント
  • PL SQL のループを使用してセレクト文を複数回実行し、パフォーマンスを測定する方法について教えてください。
  • select 変数 into を使用しないとコンパイルできず実行できない場合、同じセレクト文を複数回実行し時間を測定する方法はありますか?
  • CREATE OR REPLACE PROCEDURE を使用して、ループ内でセレクト文を実行し時間を測定する方法について教えてください。
回答を見る
  • ベストアンサー

PL SQL のループ

あるセレクト文のパフォーマンスを測定するためにループで複数回実行し時間を測定したいのですが、select 変数 into をしないとコンパイルできず実行できません。 同じセレクト文を複数回実行し時間を測定するのに良い方法は無いでしょうか? CREATE OR REPLACE PROCEDURE test IS BEGIN DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); FOR i IN 1..100 LOOP SELECT a,b,c,d,e FROM tbl; END LOOP; DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); END;

  • totmon
  • お礼率66% (213/319)
  • Oracle
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • entree
  • ベストアンサー率55% (405/735)
回答No.1

PL/SQL では INTO が必要なので、なければコンパイルできないのは当然です。INTO を使用したくないのであれば、現実的ではないですが、JDBC とか・・・。 それはさておき、SQL のパフォーマンスを正確に測定するためには SQL トレースを仕掛ける必要があります。ただし、PL/SQL だと PL/SQL ブロック自体のトレースしか取得されない場合があるので、JDBC や Pro*C を使うことがたびたびあります。 トレースの結果は tkprof をデフォルトで実行すると自動的に累計値を計算してくれます。 $ tkprof orcl_ora_8962.trc orcl_ora_8962.prf あと、SQL 文は1回実行するとキャッシュされてしまうので、毎回共有プールをフラッシュしないと正確な時間を取得することができません。 SQL> connecct / as sysdba SQL> alter system flush shared_pool;

totmon
質問者

お礼

ありがとうございました。 調べてみます。

関連するQ&A

  • 基本的なことですが;

    DATE型の変数を定義し現在の日付時刻を代入しYYYY/MM/DD:HH24:MI:SSフォーマットで 画面表示しろという 問題を与えられました。 select sysdate from dual; declare today date; today_ki date; begin select to_char (sysdate, 'yyyy/mm/dd') into today from dual; select to_char (sysdate, 'hh24:mi:ss') into today_ki from dual; dbms_output.put_line( today || ', ' || today_ki); end; / という風に作ってみたのですが うまくいきません。 どうかご教授ください><

  • Oracleでミリ秒の加算

    Oracleで秒以下の単位を含む加算の仕方を教えてください。 下記のサンプルでtargetTimeが0.5秒ずつ増えていくようにしたいのですがうまくいきません。 ちょっと書き方を変えればいいだけの事のような気がするのですが、いろいろ試したのですがうまくいきませんでした…。 よろしくお願いします。 SET SERVEROUTPUT ON FORMAT WRAPPED DECLARE targetTime TIMESTAMP(6) := TO_TIMESTAMP('2012/08/14 06:00:00', 'YYYY/MM/DD HH24:MI:SS'); vAddTime NUMBER(20, 10) := (1 / 86400) * 0.5; i integer := 0; BEGIN dbms_output.put_line('加算する値'); dbms_output.put_line(vAddTime); while (i < 10) loop dbms_output.put_line(targetTime); targetTime := targetTime + vAddTime; i := i + 1; end loop; END;

  • PL/SQLでエラー

    PL/SQLの使用方法を検討しており、下記のようにサンプルを作成しました。 //1. 宣言部 create or replace package Pac is procedure Pro1(p1 in varchar2); end; / パッケージが作成されました //2. 本体 create or replace package body Pac is procedure Pro1(p1 in varchar2) is tempdate DATE; begin select to_char(sysdate, 'yyyy/mm/dd') INTO tempdate from dual; DBMS_OUTPUT.PUT_LINE('引数は' || p1 || 'です。'); DBMS_OUTPUT.PUT_LINE('日付は' || tempdate || 'です。'); end; end; / パッケージ本体が作成されました //3. 実行 execute Pac.Pro1('a'); // エラー内容 行1でエラーが発生しました。: ORA-00900: invalid SQL statement SQLPlusより、上記の[1. 宣言部]でパッケージを作成し、[2. 本体]で本体部分を作成しました。 その後、[3. 実行]を実施しましたが、 エラーが出力されて実行されません。 何がいけないのかお気づきの点がございましたら、 よろしくお願いします。

  • PL/SQLでのTO_DATEの時間取得について

    お世話になります。 PL/SQLでDATE型のデータの日時を取得する方法を教えてください。 PL/SQLでDBの値を、TO_CHARで取ってきて、その値をTO_DATEすると、時刻が落ちてしまいます。 charWorkEndDate VARCHAR2(20); dtWorkEndDate DATE; charWorkEndDate := to_char(V00061_Rec.S_DATE5, 'YYYY/MM/DD HH24:MI:SS'); dtWorkEndDate := to_date(charWorkEndDate, 'YYYY/MM/DD HH24:MI:SS'); 出力結果 --charWorkEndDate- [2005/12/25 06:00:19] --dtWorkEndDate- [05-12-25] to_dateの1つ目の引数にシングルクォーテーションが必要かと思い、 dtWorkEndDate := to_date('''||charWorkEndDate||''', 'YYYY/MM/DD HH24:MI:SS'); としてみたのですが、その場合、「ORA-01841: (周)年は-4713と+9999の間の0以外の数を指定する必要があります」とのエラーが出てしまいます。 どなたかDATE型のデータの時刻を取る方法をご存知でしたら、教えていただけますでしょうか。 よろしくお願いします。

  • PL/SQLで

    set serveroutput on size 100000; declare wk_cnt integer; begin wk_cnt := 100; for wk_cnt in 1..10 loop … end loop; dbms_output.put_line(wk_cnt); end; / で、最後のwk_cntが10(11?)ではなく100になります。 何故でしょうか??

  • 【PL/SQL】DATE型の時刻の表示と非表示

    PL/SQLでのDATE型の取扱いについて教えてください。 初期化パラメータNLS_DATE_FORMATが'YY-MM-DD'で、 ある列を'YYYY/MM/DD HH24:MI:SS'形式でDBにINSERTしたい場合、 dtWorkEndDate := to_date(charWorkEndDate, 'YYYY/MM/DD HH24:MI:SS'); としてINSERTにdtWorkEndDateを用いると、 YY-MM-DD形式でDBに登録されてしまいます。 (dtWorkEndDateはDATE型。) ORACLEの設定かPL/SQLの問題なのかわからないのですが、 なにかアドバイスを頂けないでしょうか。 よろしくお願いします。

  • SQL*Loader  フォーマット変換について

    SQL*Loaderの制御ファイル内で、 以下のような日付データを変換するにはどうしたらよいでしょうか? ・2010-12-06 00:00:00.000 以前は'2010-12-06 00:00:00'の形式だったので "to_char(to_date(:DENPYO_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYYMMDD')" のようにして変換が可能だったのですが、仕様変更がありましてこれに対応しなければいけなくなりました。 ちなみに安易な考えで以下のようにしたのですがさすがにだめでした... "to_char(to_date(:DENPYO_DATE,'YYYY-MM-DD HH24:MI:SS.000'),'YYYYMMDD')" 方法をご存知の方がいれば是非、ご教示いただきたく存じます。 よろしくお願いいたします。

  • pl/sqlでselect文の結果をCSV出力しようとしています。(o

    pl/sqlでselect文の結果をCSV出力しようとしています。(oracle 8.16) そこで以下のようにクエリの結果を出力しようとしているのですが、 SQL文の長さが255バイト(文字?)以下ならば正常に動くのですが、 255を超えると正常な結果が返ってこない状況です。 (エラーは発生しないが、結果が1カラム分しか出力されない。) OPEN c FOR SQL文; LOOP FETCH c INTO vOutputLine; EXIT WHEN c%NOTFOUND; DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,1,100)); DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,101,100)); DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,201,100)); DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,301,100)); DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,401,100)); DBMS_OUTPUT.PUT_LINE(SUBSTR(vOutputLine,501,100)); END LOOP; CLOSE c; oracle8だとPUT_LINE などで使用できる一行のバッファサイズが 255 バイトまでという記事があったのでそれが原因かなとおもってのですが、解決方法が分かりません http://www.shift-the-oracle.com/plsql/dbms_output/ 解決方法、もしくは他に原因が検討違いでしたら教えていただけます様お願いします。

  • PL/SQLでの文字列と数値の比較について

    いつもお世話になっております。 次のように、今が午前中なら「AM」と表示するPL/SQLのプログラムを考えています。 BEGIN if TO_CHAR(SYSTIMESTAMP,'hh24')<12 THEN DBMS_OUTPUT.PUT_LINE('AM'); END if; END; / 動作しているように見えるのですが、TO_CHARはVARCHAR2型を返すとマニュアルに書いてありました。TO_CHARが返す値は数値に変換したほうがよいのでしょうか。あるいはPL/SQLでも、文字列は数値に変換されるのでしょうか。 お教えいただけると助かります。 何卒よろしくお願いいたします。

  • PL/SQL ORA-06502エラーに関して(動的SQL)

    こんにちは、いつもお世話になっております。 現在、会社で動的SQLを使用してとある開発をおこなっているのですが、 どうしても上手くいかないので、どなたか教えて下さいm(__)m 下記の動的SQL文で最後から2行目のSQL:DBMS_OUTPUT.PUT_LINE(varDel); を実行するとORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。のエラーが 発生します、過去ログやgoogleで検索をかけてみたのですが、 どうにも解決方法がわからず困っています・・・・ お知恵のある方、教えて下さいませm(__)m ※多分、sql文が長いせいだとは思うのですが、どうしても これ以上は短くできず、静的ではなく、動的で動かさなければならない という条件付きなんですが、宜しく御願いします。 DECLARE numkeepD NUMBER := 0; -- データ保管期間格納用 varAST VARCHAR2(4) := '**'; -- アクセス区分定義外格納用 varkeepD VARCHAR2(2000); -- KEEP_DAYS取得SQL文格納用 varDel VARCHAR2(2000); -- DELETE文格納用 BEGIN varkeepD := 'SELECT KEEP_DAYS FROM SMCI4T910 WHERE ACC_KBN = '''||varAST||''''; DBMS_OUTPUT.PUT_LINE(varkeepD); EXECUTE IMMEDIATE (varkeepD) INTO numkeepD; DBMS_OUTPUT.PUT_LINE(numkeepD); -- アクセスログデータ削除SQL文格納 varDel := 'DELETE FROM '||cTABLE_STCI1T910||' ST910 ' ||'WHERE ' ||'ST910.DELETE_FLG = SCIS_CTS.cDEL_NO AND ' ||'EXISTS(' ||'SELECT 1 ' ||'FROM SMCI4T910 SM910 ' ||'WHERE ' ||'ST910.ACC_KBN = SM910.ACC_KBN AND ' ||'ST910.ACC_CYMD < TO_CHAR(SYSDATE - SM910.KEEP_DAYS,''YYYYMMDD'') AND ' ||'ST910.ACC_KBN <> varAST AND ' ||'SM910.DELETE_FLG = SCIS_CTS.cDEL_NO)'; DBMS_OUTPUT.PUT_LINE(varDel); --EXECUTE IMMEDIATE (varDel) END;