我正在尝试推动一个非地理空间但非常适合的数据集的小实验,并且发现结果有点令人不安。数据集是基因组数据,例如人类基因组,我们有一个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;
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);
进入此区域的数据沿着Y维度非常密集(想象一下,就像你在很长的路上记录了每个建筑物,电话亭,邮箱和鸽子的位置)。我已经测试了R-Indexes如何在Java中使用这些数据进行测试,以及该领域的其他人已经成功地将它们应用于平面文件格式。然而,没有人将它们应用于数据库AFAIK,这是该测试的目标。
在将大量数据添加到空间模型中时,是否有人看到类似的行为?空间模型沿着特定的轴并不是非常不同?如果我反转坐标使用,问题仍然存在。如果这是一个原因,我正在运行以下设置
帮助!
还在
中引入解释计划+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+
| 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)
重写的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`)
仍然没有突出显示此查询的性能如此差的原因
在阅读@ rickonrails @Fraser发布的文章后,问题似乎与索引不在内存中有关。如果我将类似的技术应用于文章中提到的那些(确实使密钥缓冲区非常大),然后我强制查询使用索引查询时间plumet。我们仍然看到查询一个地区和一个地区之间的滞后。然后搜索该区域的一个子集,但它都指向使索引的负载正确。
这个故事的寓意是什么? MySQL中的R-Indexes在内存中具有相当差的性能,然后它们具有出色的性能。对于我想要做的事情来说,这并不是一个很好的解决方案,但它仍然为MySQL提供了一个有趣的角度。
感谢所有人的帮助。
答案 0 :(得分:1)
从EXPLAIN计划中我们看到虽然空间可能用于查询(' possible_keys'列),但它未被使用(' key'列中为NULL)。 我不确定为什么它不是自动选择的,但您可以通过使用强制索引'在查询中指定它来明确指示MySql使用索引。子句:
select count(*)
from spatial_feature
force index (sf_location_idx) -- <== this is the 'force index' clause
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location);
答案 1 :(得分:0)
目标是带回所有 与两个X相交的项目 沿着一个Y坐标 坐标
您是否考虑过使用多个字段的索引?像:
CREATE INDEX spacial_search ON spatial_feature(y, x)
如果您使用的是一组有限的y
值,则可以使用此方法。
答案 2 :(得分:0)
我拥有遗传学学位,而且我是一名程序员,你不需要使用X和Y作为你的命名法,它会变得太疯狂......你需要一个开始和一个停止位置(不是“轴”)和染色体编号。您首先通过染色体编号然后根据位置进行索引,然后将位置编入索引然后将染色体编入索引(问题:您是在处理可以有两个阅读框的真核生物或染色体吗?)
EG :(其中“x”=位置,“y”=染色体)
CREATE INDEX spatial_index_1 ON spatial_feature(chromosome, position);
CREATE INDEX spatial_index_2 ON spatial_feature(position, chromosome);
顺便说一句,染色体是非常长的字符串(就像数据一样)你可以(加速它们像blob一样转储它们(即编码基因和垃圾DNA)
答案 3 :(得分:0)
您确定要使用关系数据库吗?如果我是你,我会把你的数据集推送到Solr或Elastic Search(可能将主数据集存储在别处)。这些引擎是为索引而构建的,您会注意到响应时间的差异。