AWS DynmoDB FilterExpressionの落とし穴

ちょっとマニアックで癖のあるAWS DynmoDB。

FilterExpressionで絞り込み検索することは、多々あるかと思います。

データ一覧を、1ページ内に固定件数で表示する場合は、注意が必要です。

例えば、1ページ=50件とすると、pythonでは以下のようなコードになるかと思います。

tbl1 = dynamodb.Table("テーブル名")
   :
   :
resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          FilterExpression=Attr('フィルタ項目名').eq('フィルタ値'), 
          Limit=50 )

しかしこのままですと、対象データが存在していても、目標の50件が取り出せません。最悪0件という場合もあります。

dynamodbでは、Limitの件数を取り出した後に、FilterExpressionがかかります。

通常のRDBをご存じの方は、そんなバカな! という感じられるかと思います。ちょっとひどいですね。

Fillterして規定件数を、読み出したい場合は、以下のようにqueryをloopさせるしかありません。

reccnt=0

while( reccnt < 50 ):
   resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          FilterExpression=Attr('フィルタ項目名').eq('フィルタ値'), 
          Limit=( 50 - reccnt ) 
   )
   if reccnt == 0 :
       items = resp['Items']
   else:
       items.extend(resp['Items']) #検索集合を結合

   reccnt = len(items)

それならこれでいいと思われるかもしれませんが、queryのcall回数のオーバヘッドが生じます。特に、残り1件で、フィルタ後の件数が0が続くと、何回もループしてしまい、応答遅れが顕著に現れます。

本対策としては、FilterExpressionは使わず、予めキーとしてテーブル設計を行う必要があるようです。

しかし既にデータが蓄積された状態では、途中からキー追加は避けたいところです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です