各「列」が既知の範囲に漠然と均等に分散していると仮定すると、各列の一連のバケットと、バケットを満たす行のリストを追跡できます。各列のバケットの数は同じでも異なっていてもかまいませんが、完全に任意です。バケットが多いほど高速ですが、メモリが少し多くなります。
my table:
range: {1to10} {1to4m} {-2mto2m}
row1: {7 3427438335 420645075}
row2: {5 3862506151 -1555396554}
row3: {1 2793453667 -1743457796}
buckets for column 1:
bucket{1-3} : row3
bucket{4-6} : row2
bucket{7-10} : row1
buckets for column 2:
bucket{1-2m} :
bucket{2m-4m} : row1, row2, row4
buckets for column 3:
bucket{-2m--1m} : row2, row3
bucket{-1m-0} :
bucket{0-1m} :
bucket{1m-2m} : row1
次に、一連の基準が与えられた場合、その基準に一致するバケット{v[0]<=5, v[2]>3*10^10}
を引き出します。
column 1:
v[0]<=5 matches buckets {1-3} and {4-6}, which is rows 2 and 3.
column 2:
v[2]>3*10^10} matches buckets {2m-4m} and {4-6}, which is rows 1, 2 and 3.
column 3:
"" matches all , which is rows 1, 2 and 3.
これで、探している行が3つの基準すべてを満たしていることがわかったので、すべての基準に一致したバケット内のすべての行(この場合は行2と3)を一覧表示します。この時点で、バケットの粒度によっては、大量のデータであっても残りの行数は少なくなります。この時点で残っている各行をチェックして、それらが一致するかどうかを確認するだけです。このサンプルでは、行2が一致しているのに、行3は一致していないことがわかります。
このアルゴリズムは技術的にはO(n)ですが、実際には、小さなバケットが多数ある場合、このアルゴリズムは非常に高速になる可能性があります。