ファイル内の PL/SQL パフォーマンス データの生成とエクスポート

Visual Expert は、PL/SQL コードのパフォーマンスを解析し、その実行に関する統計情報を生成できます。この機能は、Visual Expert プロジェクト内で生成されるデータに依存しています。

このデータの生成方法は、設定に依存します。

  • Visual Expert が Oracle DB に接続できるのであれば、この手順に従う必要はありません。代わりに、 この記事に従ってください。
  • Visual Expert が Oracle に接続できない場合、例えば、別の環境でホストされている本番用データベースなどは、以下の手順に従って必要なデータを含むファイルを生成し、Visual Expert プロジェクトにインクルードします。

 

  1. SYSDBAとしてSYSに接続します。
  2. CONNECT / AS SYSDB
  3. パフォーマンス データのファイルを書き込むディレクトリを作成します。
    例: PERFDATADIRは以下のように ‘C:\ODATA’ を指します。
  4. CREATE OR REPLACE DIRECTORY PERFDATADIR AS 'C:\ODATA';
  5. ユーザがパッケージ “VEPerfUtils” を実行できるようにするために、上記で作成したディレクトリ(PERFDATADIR)のREAD AND WRITEアクセス権を付与します。
    ユーザ PERFTEST の例:
  6. GRANT READ, WRITE ON DIRECTORY PERFDATADIR TO PERFTEST;
  7. パッケージ "VEPerfUtils" を実行するために、EXECUTE ON UTL_FILEを付与します。
    ユーザ PERFTEST の例:
  8. GRANT EXECUTE ON UTL_FILE TO PERFTEST;
  9. ORACLEからのパフォーマンス データを読み込むために Select ON v_$SQL を付与します。
    ユーザ PERFTEST の例:
  10. GRANT SELECT ON v_$sql TO PERFTEST;
  11. データベースに接続します。
    例:ユーザ PERFTEST で接続
  12. この手順の最後に記載されているスクリプト VEPerfUtils.PLSQL を実行して、パッケージ VEPerfUtils を作成します。
  13. プロシージャ VEPERFUTILS.WRITEPERFORMANCEDATATOFILE を実行して、ファイル内のパフォーマンス データを読み書きします。
  14. DECLARE
    FILENAME NVARCHAR2(200);
    DIRECTORY NVARCHAR2(200);
    RECORDLIMIT NUMBER;
    BEGIN
    FILENAME := 'TestPerformanceData.veplsqlperf'; -- provide a filename. It must have the extension .veplsqlperf
    DIRECTORY := 'PERFDATADIR'; -- provide the name of the Directory object created in step #2
    RECORDLIMIT := NULL; -- provide a number to limit records or NULL to write all records
      		VEPERFUTILS.WRITEPERFORMANCEDATATOFILE(
        FILENAME => FILENAME,
        DIRECTORY => DIRECTORY,
        RECORDLIMIT => RECORDLIMIT
      );
    --rollback; 
    END;
    

 

上記のプロセスを実行してパフォーマンス ファイルの準備ができたら、Visual Expert 内で使用できます。それには、以下の手順に従ってください。

  1. Visual ExpertでOracle PL/SQLプロジェクトを開きます。
  2. リボンメニューの [管理] タブから [ソースコードの管理] に移動します。
    ファイル内の PL/SQL パフォーマンス データの生成とエクスポート
  3. [追加] アイコンをクリックして、パフォーマンス データ ファイル(*.veplsqlperf)を新しいソースコードの場所として追加します。
    ファイル内の PL/SQL パフォーマンス データの生成とエクスポート
  4. Visual Expert プロジェクト ウィザードで、[フォルダー / ファイル] を選択し、"PERFDATADIR "ディレクトリを探し、新しいソースコードの場所として追加する*.veplsqlperfファイルを探します。[終了] をクリックします。
    ファイル内の PL/SQL パフォーマンス データの生成とエクスポート
  5. 新しいエントリが *.veplsqlperf ファイルのリストに追加されます。
    ファイル内の PL/SQL パフォーマンス データの生成とエクスポート
  6. このダイアログを閉じると、Visual Expert はコード解析をリフレッシュするように通知します。[はい] をクリックします。
    ファイル内の PL/SQL パフォーマンス データの生成とエクスポート
  7. 解析プロセスが完了すると、新しい解析が自動的にロードされます。
  8. パフォーマンスを分析するために利用できる最新の機能を活用するために、この記事をご覧ください。
    コードのパフォーマンスを向上させます。.

 

==================== Source of the file VEPerfUtils.PLSQL =========================

create or replace PACKAGE BODY VEPerfUtils AS 
PROCEDURE WritePerformanceDataToFile(filename nvarchar2, directory nvarchar2, recordLimit number);
END;

/

create or replace PACKAGE BODY VEPerfUtils AS 

PROCEDURE WritePerformanceDataToFile(filename nvarchar2, directory nvarchar2, recordLimit number)
IS

cursor vsql is
	SELECT v.parsing_schema_name,v.EXECUTIONS, Round(v.elapsed_time / 1000, 3) as elapsed_time, v.sql_fulltext from 
	--PerfData
	v$sql 
	v; 

perfdata vsql%rowtype; 

verecord CLOB;
vetemprecord CLOB;
veRecordCounter number := 0;
outputFileName nvarchar2(2000);
colum_delimiter nvarchar2(10) := N'«'||N'¬'||N'»';
row_delimiter nvarchar2(10) := N'«'||N'®'||N'»';

fileReference    utl_file.file_type := NULL;
dataReadLength     NUMBER := 2000; 
startOffset  NUMBER := 1; 
dataLength  NUMBER ; 
dataBuffer    NVARCHAR2(2000); 
readCharsLen NUMBER := 0;
dataBufferLength NUMBER := 0;

BEGIN
  
    verecord := NULL; 
    outputFileName := filename || '.veplsqlperf';
    dbms_output.put_line('Opening :' || directory || outputFileName);
    
    --open file
    fileReference := utl_file.fopen_NCHAR(directory, outputFileName, 'a', 32760);

    	
    for perfdata in vsql loop 
      
      veRecordCounter := veRecordCounter + 1;

	IF (recordLimit IS NOT NULL AND veRecordCounter > recordLimit) THEN
	SYS.utl_file.fclose(fileReference);
	dbms_output.put_line('total records written :'||veRecordCounter);
	return;
	END IF;


      vetemprecord := nvl(perfdata.parsing_schema_name,'') || colum_delimiter
              	|| nvl(perfdata.EXECUTIONS, 0) || colum_delimiter 
                || nvl(perfdata.elapsed_time, 0) || colum_delimiter 
		|| nvl(perfdata.sql_fulltext, '') || colum_delimiter
		|| veRecordCounter 
		|| chr(10) || row_delimiter || chr(10);

  

      verecord := verecord || vetemprecord;
      
      IF (mod(veRecordCounter , 10) = 0) Then
	
	startOffset  := 1;
	dataLength  := nvl(dbms_lob.getlength(verecord), 0); 
	dataBuffer    := ''; 

	if(dataLength > 0) then
	
		while (startOffset < dataLength) 
		loop
			
			dataBuffer := '';
			if ((dataReadLength + startOffset) > dataLength) then
				readCharsLen := dataLength - startOffset + 1;
	dbms_lob.READ(verecord, readCharsLen, startOffset, dataBuffer);
			else
	dbms_lob.READ(verecord, dataReadLength, startOffset, dataBuffer);
			end if;

			dataBufferLength := length(dataBuffer);
			
			if(dataBufferLength > 0) then
				utl_file.putF_NCHAR(fileReference, dataBuffer);
				utl_file.fflush(fileReference);
			end if;
			
			startOffset := startOffset + dataReadLength;
		END LOOP;

		verecord := NULL;

	end if;

      End IF;
      
    end loop;

    
	startOffset  := 1;
	dataLength  := nvl(dbms_lob.getlength(verecord), 0); 
	dataBuffer    := ''; 

	if(dataLength > 0) then

		while (startOffset < dataLength) 
		loop
			
			dataBuffer := '';
			if ((dataReadLength + startOffset) > dataLength) then
				readCharsLen := dataLength - startOffset + 1;
dbms_lob.READ(verecord, readCharsLen, startOffset, dataBuffer);
			else
dbms_lob.READ(verecord, dataReadLength, startOffset, dataBuffer);
			end if;

			dataBufferLength := length(dataBuffer);
			
			if(dataBufferLength > 0) then
				utl_file.putF_NCHAR(fileReference, dataBuffer);
				utl_file.fflush(fileReference);
			end if;

			startOffset := startOffset + dataReadLength;
		END LOOP;

		verecord := NULL;

	end if;
    
	dbms_output.put_line('Completed writing Total Records to file:' || veRecordCounter);
    
--close file
utl_file.fclose(fileReference);

EXCEPTION
	WHEN OTHERS THEN
		--close file
		utl_file.fclose(fileReference);
		dbms_output.put_line('ERROR_STACK: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
		dbms_output.put_line('ERROR_BACKTRACE: ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
		DBMS_OUTPUT.put_line ( 'Error raised in: '|| $$plsql_unit ||' at line ' || $$plsql_line || ' - '||sqlerrm);
		dbms_output.put_line('Error Occurred');
		
		
END WritePerformanceDataToFile;
END VEPerfUtils;