4

問題:

選択が 2 つのインデックス付き列を含む基準に基づいているテーブルから効率的にレコードを選択する方法。

記録がありますが、

#rec{key, value, type, last_update, other_stuff}
  • キー(デフォルト)、タイプ、およびlast_update列にインデックスがあります
  • タイプは通常、アトムまたは文字列です
  • last_update は整数です (1970 年以降の UNIX スタイルのミリ秒)

たとえば、type = Type で、特定のタイムスタンプ以降に更新されたすべてのレコードが必要です。

私は次のことを行います(汚れていないトランザクションにラップされます)

lookup_by_type(Type, Since) ->
    MatchHead = #rec{type=Type, last_update = '$1', _= '_'},
    Guard = {'>', '$1', Since},
    Result = '$_',
    case mnesia:select(rec,[{MatchHead, [Guard],[Result]}]) of
    []    -> {error, not_found};
    Rslts -> {ok, Rslts}
    end.

質問

  • lookup_by_type 関数は基礎となるインデックスを使用していますか?
  • この場合、インデックスを利用するより良い方法はありますか
  • 私が取るべきまったく異なるアプローチはありますか?

皆さん、ありがとうございました

4

1 に答える 1

4

おそらく役立つ1つの方法は、QLCクエリを調べることです。これらはよりSQL/宣言型であり、可能であればIIRC自体でインデックスを利用します。

ただし、主な問題は、mnesiaのインデックスがハッシュであるため、範囲クエリをサポートしていないことです。typeしたがって、現在フィールドでのみ効率的にインデックスを作成でき、フィールドではインデックスを作成できませんlast_update

それを回避する1つの方法は、テーブルを作成してordered_setからlast_update、を主キーにすることです。keyパラメータにすばやくアクセスする必要がある場合は、パラメータにインデックスを付けることができます。ストレージの可能性の1つは、次のようなものです{{last_update, key}, key, type, ...}last_updateしたがって、注文可能であるため、クエリにすばやく回答できます。

それを回避する別の方法は、last-updateを個別に保存することです。順序集合であるテーブルを保持し、{last_update, key}それを使用して、クエリでより大きなテーブルでスキャンするものの量を制限します。

mnesiaは、小さなインメモリデータベースとして使用するのが最適であることを忘れないでください。したがって、スキャンはメモリ内にあり、したがってかなり高速であるため、必ずしも問題になるとは限りません。ただし、その主な機能は、データに対してダーティな方法でキー/値のルックアップを実行してすばやくクエリを実行できることです。

于 2012-10-17T15:04:30.590 に答える