大量のデータセットのキャッシュ

ここでは、大量のデータセットをキャッシュする必要がある場合におけるさまざまな推奨事項について説明します。

ビューのデータをキャッシュする際、キャッシュエンジンは 2 つの UPDATE ステートメントを実行しますが、キャッシュするデータセットが大量 (数億行) であると、ステートメントの実行に時間がかかることがあります。これらの UPDATE ステートメントは、以下の目的で実行されます。

  1. キャッシュテーブルの既存のデータを無効にする。

  2. 挿入された行のステータスを「処理中」から「有効」に変更する。

これら 2 つの UPDATE は同じトランザクション内で実行されます。このプロセスの詳細については、「 実行時の Full キャッシュモード 」を参照してください。

大量のデータセットを扱う場合、これらの UPDATE ステートメントで数百万行を更新する必要があります。キャッシュデータベースでトランザクションログのサイズが制限されている場合、またはデータベースでそれらのステートメントを実行するのにかかる時間を許容できない場合、この更新処理が問題になる可能性があります。このようなシナリオ向けに、キャッシュエンジンには、キャッシュロードプロセスを高速化し、トランザクションログに関する問題を防止できるオプションが用意されています。このオプションを有効にすると、ビューのキャッシュロードプロセスが以下の 3 点で変更されます。

  1. 行を「処理中」の状態で挿入してから UPDATE ステートメントを実行して「有効」に変更するのではなく、「有効」の状態で挿入します。

  2. 'cache_invalidate' = 'all_rows' である場合、UPDATE ステートメントではなく、 TRUNCATE TRACE ステートメントを実行してキャッシュテーブルをクリアします。

  3. 'cache_invalidate' = 'matching_rows' である場合、トランザクションの外部で UPDATE ステートメントを実行します。

これらのオプションを有効にするには、キャッシュロードクエリの CONTEXT 句に 'cache_atomic_operation' = 'false' を追加します。次に例を示します。

SELECT *
FROM employee
CONTEXT (
  'cache_preload' = 'true'
, 'cache_invalidate' = 'all_rows'
, 'cache_wait_for_load' = 'true'
, 'cache_return_query_results' = 'false'
, 'cache_atomic_operation' = 'false');

このパラメーターを追加することが推奨されるのは、後述するさまざまな理由によりそれが必要な場合のみですが、まずはこのパラメーターを使用すると、データをキャッシュおよび無効化する方法がどのように変わるかについて説明します。

  • Full キャッシュモード 」で説明しているように、行は「処理中」のステータスで挿入され、トランザクション内で「有効」に設定されます。

    パラメーター 'cache_atomic_operation' = 'false' を指定している場合、行は「有効」のステータスで挿入されます。これには、キャッシュエンジンが新しい行のステータスを変更するために UPDATE を実行する必要がないという利点があります。これにより、新しいデータをキャッシュテーブルに挿入する時間が短縮され、データベースのトランザクションログに関する問題が回避されます。

  • キャッシュロードクエリでパラメーター 'cache_invalidate' = 'all_rows' を指定している場合、キャッシュエンジンは、すべての行を挿入した後に UPDATE を実行して、「古い」有効な行のステータスをすべて無効に変更します。

    クエリで 'cache_atomic_operation' = 'false''cache_invalidate' = 'all_rows' を指定している場合、キャッシュエンジンは、キャッシュデータを挿入する前に TRUNCATE TABLE <cache table> を実行します。このステートメントは、テーブルのすべての行を削除します。どのデータベースでも、UPDATE を実行して行のステータスを有効から無効に変更したり、DELETE を実行してすべての行を削除したりするよりも、TRUNCATE のほうがはるかに高速です。UPDATE や DELETE と異なり、TRUNCATE はトランザクションログをバイパスするからです。

    TRUNCATE TABLE の実行後、キャッシュエンジンはキャッシュデータの挿入を開始します。

  • クエリで 'cache_atomic_operation' = 'false''cache_invalidate' = 'matching_rows' を指定している場合、キャッシュエンジンは UPDATE を実行して、クエリの WHERE 条件を満たす有効な行のステータスを変更します。その後、「有効」のステータスで新しい行の挿入を開始します。

    行を有効から無効に切り替える UPDATE ステートメントは、クエリで 'cache_atomic_operation' = 'false' を指定する場合とは異なります。このパラメーターを指定している場合、行はブロック単位で無効化されます。つまり、キャッシュモジュールは、UPDATE ステートメントを 1 回実行して一致するすべての行を無効化するのではなく、UPDATE ステートメントを複数回実行して 1 回につき一定数の行だけを無効にします。数百万行を変更する UPDATE ステートメントを 1 回実行する代わりに、UPDATE ステートメントを複数回実行することによって、たとえ更新する行数は変わらなくても、データベースのトランザクションログにかかる負荷は少なくなります。

    デフォルトでは 1 回の UPDATE で無効化される行数は 10,000 であり、キャッシュエンジンは、すべての有効な行が無効に設定されるか、または UPDATE を 100 回実行するまで、UPDATE ステートメントを繰り返し実行します。1 回の UPDATE で無効にする行数を変更するには、CONTEXT 句にパラメーター 'cache_invalidate_block_size'='<number of rows>' を追加します。これは、トランザクションログが小さいか、無効にする行数が非常に多い場合に役立つ可能性があります。次に例を示します。

SELECT *
FROM employee
CONTEXT (
'cache_preload' = 'true'
, 'cache_invalidate' = 'all_rows'
, 'cache_wait_for_load' = 'true'
, 'cache_return_query_results' = 'false'
, 'cache_atomic_operation' = 'false'
, 'cache_invalidate_block_size' = '100000')

キャッシュの構成で [Use Bulk Data Load APIs] オプション (一部のデータベースアダプターの場合のみ使用可能) がチェックされている場合、上記の操作の実行順序は同じです。唯一の違いは、キャッシュエンジンは、INSERT INTO ステートメントではなく、データベースの API を使用してデータをロードする点です。


必要な場合にのみ「'cache_atomic_operation' = 'false'」をクエリに追加する理由

以下に示すさまざまな理由により、必要な場合にのみパラメーター 'cache_atomic_operation' = 'false' を追加することが推奨されます。

  1. キャッシュロードクエリの実行中に、他のユーザーがこのビューをヒットする別のクエリを実行した場合は、そのユーザーは不完全な結果を取得します。

    この問題を回避するには、キャッシュロードクエリをダウンタイム中に実行する Scheduler ジョブをセットアップして、クライアントに影響が及ばないようにします。

  2. キャッシュプリロードクエリが失敗するか、またはキャッシュデータベースにデータを挿入している間にキャンセルされた場合、ユーザーは手動で不完全なデータを無効化する必要があります。

  3. cache_atomic_operation' = 'false''cache_invalidate' = 'matching_rows' が指定されている場合、データはブロック単位で無効化されます。ただし、Derby、Microsoft SQL Server 2000 (これより新しいバージョンはこのオプションをサポートしています)、Vertica、Netezza など、ブロック単位のデータ無効化をサポートしていないデータベースもあります。そのようなデータベースでこのオプションを使用しようとすると、Virtual DataPort はエラーを返します。

このパラメーターを指定しない場合、上記の状況はどれも発生しません。

ビューのキャッシュのブロック単位での無効化

ビューのキャッシュデータをプログラムから無効にして、新しい行をロードしないようにするには、次のステートメントを使用します。

ALTER TABLE <view name> CACHE INVALIDATE

このコマンドにより、キャッシュエンジンは、以下の処理を実行します。

  1. キャッシュデータベースでトランザクションを開始します。

  2. キャッシュテーブルに対して、有効な行のステータスを無効に切り替える UPDATE ステートメントを実行します。

  3. トランザクションをコミットします。

前述したように、数億行を変更する UPDATE を実行すると、トランザクションログに大きな負荷がかかります。トランザクションログをスキップするには、パラメーター NOATOMIC を追加します。

ALTER TABLE <view name> CACHE INVALIDATE
NOATOMIC [ INVALIDATEBLOCKSIZE <number of rows:integer> ]

NOATOMIC が指定されている場合、キャッシュエンジンは、トランザクションを開始しないで、1 回だけではなく複数回の UPDATE ステートメントを実行します。有効な行がすべて無効に切り替わるまで必要な回数だけ (ただし上限は 100 回) UPDATE を実行します。

パラメーター INVALIDATEBLOCKSIZE はオプションです。指定されている場合、UPDATE はパラメーターで渡された数の行を無効化します。指定されていない場合、1 回の UPDATE で 10,000 行を無効化します。

例:

ALTER VIEW employees
CACHE INVALIDATE
NOATOMIC INVALIDATEBLOCKSIZE 1000000;

このステートメントは、行のステータスを無効に変更する UPDATE ステートメントを複数回実行することによって、「employees」ビューのキャッシュを無効化します。1 回の UPDATE で 100 万行を変更し、キャッシュエンジンによって実行されます。


UPDATE ステートメントがビューを無効化する最大回数の制限値 (デフォルトは 100) を変更するには、以下を実行します。

SET 'com.denodo.vdb.util.tablemanagement.blockDelete.loopSize' = '<new value:integer>';