テーブルBlah(緯度浮動小数点数、経度浮動小数点数、create_time date、owner_id int、.....)がありました
私のコードは単一のクエリのみを実行します
select *
from Blah
where latitude < l1 and latitude > l2
and longitude < ll1 and longitude > ll2
and create_time < t1 and create_time > t2
and owner_id < o1 and owner_id > o2 ;
(もちろん、値l1、l2、....o1、o2はプログラムからの動的パラメーターです)
私の質問は、どのような種類のインデックスを作成する必要があるかです。合成指数?複合インデックスの場合、どの列を最初に配置する必要がありますか? インデックスの効果は?
私はこれについて長い間考えていましたが、オラクルのインデックスがどのように機能するかについての詳細なドキュメントを見つけることができませんでした.
私たちの場合、B ツリーを使用して実装されているドキュメントを見つけることができます。注文。
次に、上記のクエリの場合、順序が (owner_id、create_time、緯度、経度) であると仮定すると、オラクルは最初にポイント ( o1、t1、l1、ll1) までバイナリ検索する必要があると思います。この操作では、インデックスは確かに使える。しかし次に、この最初の境界の終点を見つける必要があります: (o1,t1, l1, ll2 ) を見つける必要があります。これは二分探索でも行うことができます。
次に、条件を満たす次のセクションを見つける必要があるため、(o1, t1, lx, ll1 ) を見つける必要があります。ここで、lx は l1 よりも大きい次の値です。これも二分探索で見つけることができます。しかし、私たちの場合、同じ緯度に対して経度は 1 つしか存在しない可能性が非常に高いため、ここではバイナリ サーチはリニア スキャンよりも効果的ではありません。
この精神に従って、ポイントが数日しか作成されない場合は、値の範囲のカーディナリティが小さい列 (この場合は create_time) を最初に配置する必要があるようです。また、範囲条件を実行せず、等号 (=) 条件のみを実行する場合、どの列が最初かは問題ではありませんよね?
わかりやすくするために、より簡単な例を次に示します。
XとYの2つの列があるとしましょう
データベースでは、両方の値が [1,2,....100] であるため、100x100 行になります。
私のクエリは
select * from mytable where X > 34 and X < 78 and Y > 12 and Y < 15;
インデックスが (X, Y) にあるとすると、2 つの値の比較規則は次のようになります。
v1 < v2 <=====> v1.x < v2.x || v1.x == v2.x && v1.y < v2.y
上記の順序付けルールを考えると、インデックスの値が (x、y の値) のように連続して配置されていることがわかります。
1,1, 1,2 1,3 .... 1,100
2,1 2,2 2,3 ......2,100
.....
100,1 100,2 ....... 100,100
ここで、クエリで値を検索するには、B ツリー トラバーサルで (78-34-1) 間隔を見つける必要があるため、(78-34-1)*2 ルックアップ (最初は 1 つ、最後の場所は 1 つ) 、2回のルックアップだけではありません。
したがって、次元が高くなると、間隔カウントは次元の数に応じて指数関数的に増加するため、インデックス作成はもはや役に立たない可能性があります ------ これは私の懸念事項です
どうもありがとうヤン