提高具有大型3D点数据集的SELECT查询的性能

时间:2011-02-11 21:32:17

标签: mysql sql

我有一个大型数据集(大约190万行)我正在选择的3D点。我最常使用的陈述类似于:

SELECT * FROM points 
WHERE x > 100 AND x < 200 
AND   y > 100 AND y < 200 
AND   z > 100 AND z < 200 
AND otherParameter > 10

我有x,y和z以及otherParameter的标记。我也试过为x,y,z添加一个多部分索引,但这没有帮助。

有关如何更快地进行此SELECT查询的任何建议吗?

2 个答案:

答案 0 :(得分:6)

B-Tree索引对这样的查询没有多大帮助。

作为R-Tree索引需要什么,以及对它的最小边界平行六面体查询。

不幸的是,MySQL不支持R-Tree3d点以上的2d个索引,仅X。但是,您可以在YB-Tree上创建一个索引,这对XY上的任何ALTER TABLE points ADD xy POINT; UPDATE points SET xy = Point(x, y); ALTER TABLE points MODIFY xy POINT NOT NULL; CREATE SPATIAL INDEX sx_points_xy ON points (xy); SELECT * FROM points WHERE MBRContains(LineString(Point(100, 100), Point(200, 200), xy) AND z BETWEEN 100 and 200 AND otherParameter > 10; 索引更具选择性单独:

MyISAM

仅当您的表格为{{1}}时才可以这样做。

答案 1 :(得分:-1)

我没有测试mySQL,但我很好奇它的INTERSECT有多高效:

     select points.*
     from points 
     join 
     ( 
     select id from points where   x > 100 AND x < 200 
     intersect
     select id from points where   y > 100 AND y < 200 
     intersect
     select id from points where   z > 100 AND z < 200 
     ) as keyset
     on points.id = keyset.id

不一定推荐这个 - 但是要尝试一下,特别是如果你在x,y和z上有单独的索引。

编辑:由于mySQl不支持INTERSECT,因此可以使用内联视图的JOINS重写上述查询。每个视图都包含一个键集,每个视图都具有您在x,y和z上放置的单独索引的优势。性能取决于返回的键的numnber和交叉/连接算法。

我首先测试了交叉方法(在SQLite中),看看是否有办法提高空间查询的性能,而不是使用它们的R-Tree模块。 INTERSECT实际上比在其中一个空间值上使用单个非复合索引慢,然后扫描基表的子集以获得其他空间值。但结果可能会有所不同,具体取决于数据库的大小。在表达到庞大的大小并且磁盘i / o作为性能因素变得更加重要之后,交叉离散键集可能更有效,每个离散键集都已经从索引实例化,而不是扫描基表的次要表。到索引的初始获取。