在MySQL中使用空间索引时性能不佳

and*_*atz 9 mysql database gis performance spatial

我正在尝试推动一个非地理空间但非常适合的数据集的小实验,并且发现结果有些令人不安.数据集是基因组数据,例如人类基因组,其中我们有一个DNA区域,其中像基因这样的元素占据特定的起始和终止坐标(我们的X轴).我们有多个DNA区域(染色体)占据Y轴.目标是将沿着单个Y坐标交叉两个X坐标的所有项目带回,例如LineString(START 1,END 2).

这个理论看起来很合理,所以我将它推入现有的基于MySQL的基因组计划,并提出了一个表结构,如:

CREATE TABLE `spatial_feature` (
  `spatial_feature_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `external_id` int(10) unsigned NOT NULL,
  `external_type` int(3) unsigned NOT NULL,
  `location` geometry NOT NULL,
  PRIMARY KEY (`spatial_feature_id`),
  SPATIAL KEY `sf_location_idx` (`location`)
) ENGINE=MyISAM;
Run Code Online (Sandbox Code Playgroud)

external_id表示我们在此表中external_type编码的实体的标识符并对其来源进行编码.一切看起来都不错,我推出了一些初步数据(30,000行),似乎效果很好.当这个增加超过300万行标记时,MySQL拒绝使用空间索引,并且当它被迫使用它时速度较慢(使用全表扫描时为40秒对5秒).当添加更多数据时,索引开始被使用,但性能损失仍然存在.强制索引关闭将查询降低到8秒.我正在使用的查询如下:

select count(*)
from spatial_feature
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location);
Run Code Online (Sandbox Code Playgroud)

进入这个数据的数据沿着Y维度是非常密集的(想象一下,就像你在很长的路上记录了每个建筑物,电话亭,邮箱和鸽子的位置).我已经测试了R-Indexes如何在Java中使用这些数据进行测试,以及该领域的其他人已经成功地将它们应用于平面文件格式.然而,没有人将它们应用于数据库AFAIK,这是该测试的目标.

有没有人在向空间模型添加大量数据时看到类似的行为,而空间模型沿着特定的轴并不是非常不同?如果我反转坐标使用,问题仍然存在.如果这是一个原因,我正在运行以下设置

  • MacOS 10.6.6
  • MySQL 5.1.46

救命!

还带来解释计划

+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+
| id | select_type | table           | type | possible_keys   | key  | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | spatial_feature | ALL  | sf_location_idx | NULL | NULL    | NULL | 3636060 |    33.33 | Using where |
+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

重写的SQL如下所示

select count(0) AS `count(*)` from `arabidopsis_thaliana_core_7_60_9`.`spatial_feature` where intersects(geometryfromtext('LineString(7420023 1, 7420023 1)'),`arabidopsis_thaliana_core_7_60_9`.`spatial_feature`.`location`)
Run Code Online (Sandbox Code Playgroud)

仍然没有强调为什么这个查询的性能如此差

在阅读了来自rickonrails的@Fraser发布的文章后,问题似乎与索引不在内存中有关.如果我将类似的技术应用于文章中提到的那些(确实使密钥缓冲区非常大),然后我强制查询使用索引查询次数plumet.我们仍然看到在查询区域然后搜索区域的子集之间存在滞后,但它们都指向使索引的负载正确.

这个故事的寓意是什么?MySQL中的R-Indexes在内存中具有相当差的性能,然后它们具有出色的性能.对于我想要做的事情来说,这并不是一个很好的解决方案,但它仍然为MySQL提供了一个有趣的角度.

感谢所有人的帮助.

vbe*_*nce 0

目标是返回沿单个 Y 坐标与两个 X 坐标相交的所有项目

您是否考虑过使用具有多个字段的索引?喜欢:

CREATE INDEX spacial_search ON spatial_feature(y, x)
Run Code Online (Sandbox Code Playgroud)

如果您正在使用一组有限的y值,那么这就是方法。