1

ストアドプロシージャで使用される永続テーブルをグローバル一時テーブルに変換しようとしています。これらの永続テーブルの統計を確認しましたが、数千万行のデータがあり、サイズがギガバイト(最大10 GB)の場合はオーダーです。

それで、

CREATE TABLE my_table (  
  column1 NUMBER,  
  column2 NUMBER,  
  etc...  
)  
TABLESPACE BIGTABLESPACE  
NOLOGGING  
NOCOMPRESS  
NOCACHE  
NOPARALLEL  
MONITORING;  

になる必要があります

CREATE GLOBAL TEMPORARY TABLE my_table (  
  column1 NUMBER,  
  column2 NUMBER,  
  etc..  
)  
ON COMMIT PRESERVE ROWS;  

既存の永続テーブルごとに、セッションが終了するまで保持する必要がある行を含む同等のグローバル一時テーブルを作成しています。このグローバル一時テーブルは、永続テーブルの代わりにプロシージャで使用されます。
EXECUTE IMMEDIATE 'TRUNCATE ...'開始時、およびINSERT /*+ APPEND */ INTO後の時点で)

すべての永続テーブルは大きなテーブルスペースに作成されていますBIGTABLESPACE

Oracleのドキュメントには、グローバル一時テーブルがユーザーの一時テーブルスペースに作成されると記載されています(これはと思いますTEMP)。これに伴う問題は、TEMP表領域が小さく、エクステントが手順中に拡張するのに必要なサイズに拡張するように設定されていないことです。

TEMP領域は、データベースの作成中に作成されました

create database "$oracle\_sid"  
   user sys identified by "$sys\_password"  
   user system identified by "$system\_password"  
   set default bigfile tablespace  
   controlfile   reuse  
   maxdatafiles  256  
   maxinstances  $maxinstances  
   maxlogfiles   16  
   maxlogmembers 3  
   maxloghistory 1600  
   noarchivelog  
   character set WE8MSWIN1252  
   national character set AL16UTF16  
   datafile  
      '$oracle\_home/oradata/$oracle\_sid/system01.dbf' size 512M  
   logfile  
      '$oracle\_home/oradata/$oracle\_sid/redo01.log' size 1G,  
      '$oracle\_home/oradata/$oracle\_sid/redo02.log' size 1G,  
      '$oracle\_home/oradata/$oracle\_sid/redo03.log' size 1G  
   sysaux datafile  
      '$oracle\_home/oradata/$oracle\_sid/sysaux01.dbf' size 256M  
   default temporary tablespace temp tempfile  
      '$oracle\_home/oradata/$oracle\_sid/temp01.dbf' size 5G  
   undo tablespace "UNDOTBS1" datafile  
      '$oracle\_home/oradata/$oracle\_sid/undotbs01.dbf' size 5G;  

永続テーブル(私が置き換えることを計画している)は、もともとテーブルスペースに作成されましたBIGTABLESPACE

-- 50G bigfile datafile size  
create bigfile tablespace "BIGTABLESPACE"  
datafile '$oracle\_home/oradata/$oracle\_sid/bts01.dbf' size 50G  
extent management local  
segment space management auto;  

永続テーブルインデックスは、もともとテーブルスペースで作成されましたBIGTABLESPACE

-- 20G bigfile datafile size  
create bigfile tablespace "BIGINDXSPACE"  
datafile '$oracle\_home/oradata/$oracle\_sid/btsindx01.dbf' size 20G  
extent management local  
segment space management auto;  
  • これらの永続テーブルをグローバル一時テーブルに置き換えることは可能ですか?
  • TEMP表領域では、TEMP表領域の拡張で問題が発生します。表領域にグローバル一時テーブルとそのインデックスを作成する方法はありますBIGTABLESPACEBIGINDXSPACE
  • TEMPそうでない場合、テーブルスペースをビッグファイルテーブルスペースのように動作させ、インデックス/テーブルの分離を実現するにはどうすればよいですか?
  • 2つのTEMPbigfileテーブルスペースを作成し、1つにインデックスを作成し、別のテーブルにテーブルを作成できますか?

グローバル一時テーブルを使用したいのですが、プロシージャで処理するデータの量は、グローバル一時テーブルの意図した設計を超えているように見えます。助言がありますか?

4

3 に答える 3

4

データとインデックスを別々の表領域に分離することには、類似したオブジェクトをグループ化することでDBAをより快適にする可能性がある以外に利点はありません。インデックスとデータを分離することはパフォーマンス上の理由から有益であるという長年の神話がありますが、それは正しくありません。

一時オブジェクトは、一時表領域に格納する必要があります(格納する必要があります)。これらの大きな一時表領域を別の表領域に分離する場合は、TEMP表領域のサイズを増やすか、これらのオブジェクトを所有するユーザー専用に別の一時表領域を作成できます。それらを永続表領域に格納することはできません(また、格納したくないでしょう)。

ただし、アーキテクチャ的には、システムに一時テーブルが必要な理由について非常に興味があります。一時テーブルに数十GBを書き込んでいるセッションがあり、おそらく別の場所にデータを書き込むためにそれらの数十GBを再度読み取る場合、より効率的な解決策があるのではないかと思う傾向があります。Oracleでは一時テーブルが必要になることは非常にまれです。他のデータベースでは、リーダーがライターをブロックして、作業する前にテーブルからデータをコピーする必要がある場合がはるかに一般的です。Oracleにはそのような制限はありません。

于 2009-12-09T17:11:01.830 に答える
1

あなたの説明には、GTTを魅力的にしないものは何もないと思います。明らかに非常に大きな一時表領域が必要ですが、テーブル圧縮を多用していない限り、全体としてより多くのスペースを消費することはありません(GTTでは少なくとも10gR2までは使用できません)。表領域グループの使用を調べます:http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/tspaces.htm#ADMIN01103

単一の一時表領域ではなく表領域グループを使用すると、特に多くのパーティションがある表で、1つの表領域がソートの結果を保持するのに不十分な場合に発生する問題を軽減できます。表領域グループにより、単一の並列操作で並列実行サーバーが複数の一時表領域を使用できるようになります。

また、サブクエリファクタリング句の使用をおろそかにしないでください。多くの場合、一時テーブルの使用を置き換えることができます。ただし、SQFCからの大きな結果セットがディスクに流出して大量のメモリの消費を回避できるため、同じくらいの一時ストレージスペースが必要になる場合があります。そのため、TEMPスペースの増加を続行する必要があります。新しい一時テーブルが必要になるたびに新しいデータベースオブジェクトをデプロイする必要がないため、非常に便利です。

于 2009-12-10T09:32:09.230 に答える
0

移行の演習のために、大きなサイズのグローバル一時テーブルを調べました。それは機能しましたが、デバッグと拒否のハドリングのために、私は最終的にプレーンテーブルを使用しました。

GTTが機能しない場合は、行レベルのセキュリティ/ VPD(またはビュー)のいずれかを検討してください。sys_context('USERENV'、'SESSIONID')から派生した列を作成し、それを使用して、ユーザーが自分のデータのみを表示できるようにすることができます。

それでも、数ギガバイトのデータセットを同時に処理する複数のセッションについて考えるのは少し怖いです。

PS。プロシージャを介して使用されるGTTの場合、プロシージャ所有者の一時テーブルスペースではなく、セッションユーザーの一時テーブルスペースを使用すると思います。セッションを個別のOracleユーザーとして取得できる場合は、ファイルIOをさまざまなテーブルスペースに分散させる機会があります。

于 2009-12-09T23:18:13.730 に答える