DECLARE - Amazon Redshift

DECLARE

新しいカーソルを定義します。カーソルを使用して、大きなクエリセットの結果から、一度で数行を取得します。

カーソルの最初の行が取得されると、必要に応じて、結果セット全体がリーダーノード、メモリ内、またはディスク上にマテリアライズされます。大きな結果セットにカーソルを使用すると、パフォーマンスが低下する可能性があるため、可能な限り、別の方法を使用することをお勧めします。詳細については、「カーソルを使用するときのパフォーマンスに関する考慮事項」を参照してください。

カーソルは、トランザクションブロック内で宣言する必要があります。1 つのセッションで、同時に開くことができるカーソルは 1 つのみです。

詳細については、「FETCH」、「CLOSE」を参照してください。

構文

DECLARE cursor_name CURSOR FOR query

パラメータ

cursor_name

新しいカーソルの名前。

query

カーソルを作成する SELECT ステートメント。

DECLARE CURSOR の使用に関する注意事項

クライアントアプリケーションが ODBC 接続を使用し、クエリで作成される結果セットが大きすぎてメモリが足りなくなる場合、カーソルを使用して、結果セットをクライアントアプリケーションに渡すことができます。カーソルを使用すると、結果セット全体がリーダーノードでマテリアライズされ、クライアントが少しずつ結果を取得できるようになります。

注記

ODBC for Microsoft Windows でカーソルを有効にするには、Amazon Redshift で使用する ODBC DSN で [Use Declare/Fetch (宣言/フェッチを使用)] オプションを有効にします。マルチノードクラスターでは、ラウンドトリップを最小限に抑えるために、ODBC キャッシュサイズを設定し、ODBC DSN オプションダイアログの [Cache Size (キャッシュサイズ)] フィールドを 4,000 以上に設定することをお勧めします。単一ノードクラスターでは、キャッシュサイズを 1,000 に設定します。

カーソルを使用すると、パフォーマンスが低下する可能性があるため、可能な限り、別の方法を使用することをお勧めします。詳細については、「カーソルを使用するときのパフォーマンスに関する考慮事項」を参照してください。

Amazon Redshift のカーソルは、次の制限付きでサポートされています。

  • 1 つのセッションで、同時に開くことができるカーソルは 1 つのみです。

  • カーソルはトランザクション内 (BEGIN ... END) で使用する必要があります。

  • すべてのカーソルの累積結果セットの最大サイズは、クラスターノードタイプに基づいて制限されます。より大きな結果セットが必要な場合は、XL または 8XL ノード構成にサイズ変更できます。

    詳細については、「カーソルの制約」を参照してください。

カーソルの制約

カーソルの最初の行が取得されると、結果セット全体がリーダーノードにマテリアライズされます。結果セットをメモリに格納できない場合、必要に応じてディスクに書き込まれます。リーダーノードの整合性を保護するために、Amazon Redshift はクラスターのノードタイプに基づいてすべてのカーソルの結果セットのサイズに制約を適用します。

次の表に、各タイプのクラスターノードの結果セットの最大合計サイズを示します。結果セットの最大サイズの単位は、メガバイトです。

ノードの種類 クラスターあたりの最大結果セット (MB)

DC2 Large 複数ノード

192,000

DC2 Large 単一ノード

8,000

DC2 8XL 複数ノード

3,200,000

RA3 16XL 複数ノード

14,400,000

RA3 4XL 複数ノード

3,200,000

RA3 XLPLUS 複数ノード

1,000,000

RA3 XLPLUS シングルノード

64,000

RA3 LARGE 複数ノード

240,000

RA3 LARGE 単一ノード

8,000

Amazon Redshift Serverless

150,000

クラスターのアクティブなカーソル設定を表示するには、スーパーユーザー権限で STV_CURSOR_CONFIGURATION システムテーブルに対してクエリを実行します。アクティブなカーソルの状態を表示するには、STV_ACTIVE_CURSORSシステムテーブルに対してクエリを実行します。ユーザーは自分のカーソルの行のみを表示できますが、スーパーユーザーはすべてのカーソルを表示できます。

カーソルを使用するときのパフォーマンスに関する考慮事項

カーソルによって結果セット全体がリーダーノードでマテリアライズされてから、結果をクライアントに返す処理が始まるため、非常に大きな結果セットにカーソルを使用すると、パフォーマンスが低下する可能性があります。非常に大きな結果セットには、カーソルを使用しないことを強くお勧めします。アプリケーションが ODBC 接続を使用する場合など、状況によっては、カーソルのみが実行可能な解決策の場合があります。ただし、可能な限り、次の代替方法を使用することをお勧めします。

  • UNLOAD を使用して大きなテーブルをエクスポートします。UNLOAD を使用すると、複数のコンピューティングノードが同時に機能し、Amazon Simple Storage Service のデータファイルに直接データを転送します。詳細については、「Amazon Redshift でのデータのアンロード」を参照してください。

  • クライアントアプリケーションで JDBC の fetch size パラメータを設定します。JDBC 接続を使用し、クライアント側のメモリ不足エラーが発生する場合、JDBC の fetch size パラメータを設定することで、ユーザーが少量の結果セットを取得するように指定できます。詳細については、「JDBC フェッチサイズパラメータの設定」を参照してください。

DECLARE CURSOR の例

次の例では、LOLLAPALOOZA というカーソルを宣言し、Lollapalooza イベントの売り上げ情報を選択した後、カーソルを使用して結果セットから行を取得します。

-- Begin a transaction begin; -- Declare a cursor declare lollapalooza cursor for select eventname, starttime, pricepaid/qtysold as costperticket, qtysold from sales, event where sales.eventid = event.eventid and eventname='Lollapalooza'; -- Fetch the first 5 rows in the cursor lollapalooza: fetch forward 5 from lollapalooza; eventname | starttime | costperticket | qtysold --------------+---------------------+---------------+--------- Lollapalooza | 2008-05-01 19:00:00 | 92.00000000 | 3 Lollapalooza | 2008-11-15 15:00:00 | 222.00000000 | 2 Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 3 Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 4 Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 1 (5 rows) -- Fetch the next row: fetch next from lollapalooza; eventname | starttime | costperticket | qtysold --------------+---------------------+---------------+--------- Lollapalooza | 2008-10-06 14:00:00 | 114.00000000 | 2 -- Close the cursor and end the transaction: close lollapalooza; commit;

次の例では、テーブルのすべての結果を refcursor でループ処理しています。

CREATE TABLE tbl_1 (a int, b int); INSERT INTO tbl_1 values (1, 2),(3, 4); CREATE OR REPLACE PROCEDURE sp_cursor_loop() AS $$ DECLARE target record; curs1 cursor for select * from tbl_1; BEGIN OPEN curs1; LOOP fetch curs1 into target; exit when not found; RAISE INFO 'a %', target.a; END LOOP; CLOSE curs1; END; $$ LANGUAGE plpgsql; CALL sp_cursor_loop(); SELECT message from svl_stored_proc_messages where querytxt like 'CALL sp_cursor_loop()%'; message ---------- a 1 a 3