0

全て-

私のソリューションの 1 つとして、MySQL がついに成長したと思います。現在、オブジェクトの x、y、z を 3D 空間に単純に格納する 7,000 万行があります。残念ながら、挿入/クエリを処理するためにデータベースを最適化する方法が他にわかりません。距離に基づいてクエリを実行する必要があります (距離内のオブジェクトを取得します)。

良い代替品について誰か提案がありますか?同様の問題に遭遇する可能性があるため、hbase や非リレーショナル データベースなどを調べる必要があるかどうかはわかりません。通常、1 分あたり約 100 行を挿入します。クエリは次のようになります。

// get objects within 500 yards
SELECT DISTINCT `object_positions`.`entry` FROM `object_positions` WHERE  `object_positions`.`type` = 3 AND `object_positions`.`continent` = '$p->continent' AND SQRT(POW((`object_positions`.`x` - $p->x), 2) + POW((`object_positions`.`y` - $p->y), 2) + POW((`object_positions`.`z` - $p->z), 2)) < 500;

それほど複雑なことはありませんが、関連する数学が MySQL の爆発的な原因だと思います。クラウドベースのデータベース ソリューションを検討すべきかどうか疑問に思っています。1 秒あたり 10 ~ 100 件のクエリを簡単に処理する必要があります。

4

1 に答える 1

3

問題を引き起こしているのは MySQL ではなく、問題にインデックスを適用する必要があるためです。NoSQL やクラウド コンピューティングをいくら使っても魔法のように解決できないという問題があります。

わかりやすくするために、クエリを少し簡略化したものを次に示します。

SELECT DISTINCT entry 
           FROM object_positions 
          WHERE type = 3 
            AND continent = '$p->continent'
            AND DIST(x,$p->x, y, $p->y, z,$p-z) < 500

DIST() は、デカルト距離関数の省略形です。

テーブルの x、y、z に個別のインデックスを配置する必要がある場合は、次のようにする必要があります。

SELECT DISTINCT entry 
           FROM object_positions 
          WHERE type = 3 
            AND continent = '$p->continent'
            AND x BETWEEN ($p->x - 500) AND ($p->x + 500)
            AND y BETWEEN ($p->y - 500) AND ($p->y + 500)
            AND z BETWEEN ($p->z - 500) AND ($p->z + 500)
            AND DIST(x,$p->x, y, $p->y, z,$p-z) < 500

ステートメントの 3 つのBETWEEN句により、WHEREインデックスを使用して、クエリごとにテーブルの完全なテーブル スキャンを回避できます。彼らは、候補点を囲む 1000x1000x1000 のキューブ内のすべての点を選択します。次に、DIST 計算は、必要な半径の外側にあるものを破棄します。同じバッチのポイントを獲得できますが、はるかに効率的です。

実際に DIST 関数を作成する必要はありません。あなたの質問にある式は問題ありません。

(種類、大陸) の索引がありますね。そうでない場合は、それも必要です。

于 2013-02-10T19:43:42.340 に答える