0

全部-

我认为我的解决方案之一终于超越了 MySQL。现在我有 7000 万行,它们只是将对象的 x、y、z 存储在 3D 空间中。不幸的是,我不知道如何优化我的数据库来处理插入/查询了。我需要根据距离进行查询(获取距离内的对象)。

有人对好的替代品有建议吗?我不知道我是否应该查看 hbase 或非关系数据库之类的东西,因为我可能会遇到类似的问题。我通常每分钟插入大约 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 爆炸的原因,我想知道我是否应该研究基于云的数据库解决方案?它很容易每秒处理 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

该语句的三个BETWEEN子句WHERE将允许使用索引来避免对每个查询的表进行全表扫描。他们将在候选点周围的 1000x1000x1000 立方体中选择所有点。然后 DIST 计算将抛出您想要的半径之外的那些。您将获得相同批次的积分,但效率更高。

您不必实际创建 DIST 函数;您在问题中的公式很好。

您确实有(类型,大陆)的索引,不是吗?如果不是你也需要它。

于 2013-02-10T19:43:42.340 回答