投影? 結構です


カットの下には、空間インデックスの使用に関する小さなメモがあります
zcurveに基づいて、球体にあるポイントデータにインデックスを付けます。 また、PostgreSQLのベンチマークと同じ(ただし完全に異なる)との比較
Rツリーのインデックス。

トピックの開発中( 1、2、3、4、5、6 )。
実際、 最初に戻ります-地理座標にインデックスを付けて、それらを球の表面に配置するというアイデアです。 緯度と経度のペアの通常のインデックス付けでは、赤道から遠く離れた歪みが生じますが、投影の操作は普遍的ではありません。 したがって、地理座標を3次元空間に変換するという考え方は非常にエレガントに見えます。

考え方自体は新しいものではなく、同様に機能します。たとえば、PostgreSQL拡張機能-PGSphereは 、インデックス作成に3次元Rツリーを使用します。 彼と比較します。

データ準備。


PGSphere



Zorder



試験準備


PGSphere


テストには、このawkスクリプトが必要です

 #--- gentest.awk ------- BEGIN{ pi=3.1415926535897932; degra=pi/180.0; rad=180.0/pi; Grad = 1000000.; } { x = $1; y = $2; z = $3; r3 = sqrt(x*x + y*y + z*z); x *= Grad / r3; y *= Grad / r3; z *= Grad / r3; r2 = sqrt(x*x + y*y); lat = atan2(z, r2) * rad; lon = 180. + atan2(y, x) * rad; # EXPLAIN (ANALYZE,BUFFERS) printf ("select count(1) from spoint_data where sp @'<(%14.10fd,%14.10fd),.316d>'::scircle;\n", lon, lat); } 

このスクリプトは、データを準備したスクリプトと完全に対称です。 数値.316に注意する価値があります。これは、データを探している計算されたランダムなポイントを中心とする球体の半径です

一連のクエリの準備は次のように行われます。

 ./random 1000000 100 1023 | gawk -f gentest.awk >tests1.sql 

ここで、100はテストシリーズのサイズ、1023はランダマイザーのシードです。

ズカーブ


テストには、awkスクリプトも必要です。

 #--- gentest2.awk ------- BEGIN{ pi=3.1415926535897932; degra=pi/180.0; rad=180.0/pi; Grad = 1000000.; } { x = $1; y = $2; z = $3; r3 = sqrt(x*x + y*y + z*z); x *= Grad / r3; y *= Grad / r3; z *= Grad / r3; ix = int(x+0.5+Grad); iy = int(y+0.5+Grad); iz = int(z+0.5+Grad); # EXPLAIN (ANALYZE,BUFFERS) lrad = int(0.5 + Grad * sin(.316 * degra)); print "select count(1) from zcurve_3d_lookup_tidonly('zcurve_test_points_3d', "ix-lrad","iy-lrad","iz-lrad","ix+lrad","iy+lrad","iz+lrad");"; } 

このスクリプトは、データを準備したスクリプトと完全に対称です。 繰り返しますが、数値.316に注意してください。これは、データを探している計算されたランダムなポイントを中心とする立方体の半分の辺です。

一連のクエリの準備は次のように行われます。

 ./random 1000000 100 1023 | gawk -f gentest2.awk >tests2.sql 

ここで、100はテストシリーズのサイズ、1023はランダマイザーのシードです。pgsphereのサイズと一致する方が良いでしょう。

ベンチマーク


前と同様に、2つのコアと4 GBのRAMを備えた控えめな仮想マシンで測定が実行されたため、時間に絶対値はありませんが、読み取られたページ数は信頼できます。

ホットサーバーと仮想マシンでの2回目の実行で時間が表示されます。 読み取られたバッファーの数は、新しく生成されたサーバー上にあります。
半径AVG NPointsNreq種類時間(ミリ秒)読みますヒット数
.01°1.17
0.7631
(0.7615)
10,000zcurve
rtree
.37
.46
1.4397
2.1165
9.5647
3.087
.0316°11.6
7.6392
(7.6045)
10,000zcurve
rtree
.39
.67
2.0466
3.0944
20.9707
2.7769
.1°115.22
76.193
(76.15)
1,000zcurve
rtree
.44
2.75 *
4.4184
6.073
82.8572
2.469
.316°1145.3
758.37
(760.45)
1,000zcurve
rtree
.59
18.3 *
15.2719
21.706
401.791
1.62
1.°11310
7602
(7615)
100zcurve
rtree
7.2
94.5 *
74.9544
132.15
1651.45
1.12
どこで
半径 -検索エリアのサイズ(度)
Npoints- 括弧内の出力の平均ポイント数-理論的に予想される数
(41252.96平方度、1億ポイント、1平方度あたり〜2424ポイントの範囲内)
Nreq-シリーズ内のクエリの数
タイプ -
「zcurve」-それは
「rtree」-PGSphere
時間(ミリ秒) -平均クエリ実行時間
読み取り -要求ごとの読み取りの平均数
ヒット -バッファアクセスの数

*ある時点で、Rツリーのパフォーマンスが突然開始される
サグ、これは、このツリーがより顕著に読むという事実による
ページとそのワーキングセットがキャッシュに収まらなくなります(明らかに)。

zcurveはより多くのデータを見つけることに注意してください。 PGSphereのような球ではなく、キューブ内を検索します。 したがって、 HAVERSINEスタイルのポストフィルタリングが必要です 。 ただし、ここではインデックスのパフォーマンスのみを比較しています。

違いを評価してみましょう。 一般に、立方体の内部にある球の一部の面積を見つけるタスクは簡単ではありません。 評価を試みてみましょう。

Source: https://habr.com/ru/post/J338088/


All Articles