背景:
我需要将以下数据存储在数据库中:
带有标签的 osm 节点;
带有权重的 osm 边(即从 .osm 文件中的“方式”中提取的两个节点之间的边)。
形成边的节点,在相同的“路”集合中应该具有与那些路相同的标签,即,作为高速公路的“路”节点集合中的每个节点都应该具有“高速公路”标签。
我需要这种结构来轻松生成基于各种过滤器的图,例如仅由节点和边组成的图,即高速公路,或“人行道”图等。
问题:
我之前没有听说过空间索引,所以我只是将一个 .osm 文件解析为 MySQL 数据库:
- 所有节点到“节点”表(具有各自的坐标列) - 好的,在我的情况下大约有 9,000,000 行:
(INSERT INTO nodes VALUES [pseudocode]node_id,lat,lon[/pseudocode]
;
- 'edges' 表的所有方式(通常一种方式会创建一些边) - 好的,还有大约 9,000,000 行:
(INSERT INTO edges VALUES [pseudocode]edge_id,from_node_id,to_node_id[/pseudocode]
;
- 向节点添加标签,计算边的权重 -问题:
这是有问题的 php 脚本:
$query = mysql_query('SELECT * FROM edges');
$i=0;
while ($res = mysql_fetch_object($query)) {
$i++;
echo "$i\n";
$node1 = mysql_query('SELECT * FROM nodes WHERE id='.$res->from);
$node1 = mysql_fetch_object($node1);
$tag1 = $node1->tags;
$node2 = mysql_query('SELECT * FROM nodes WHERE id='.$res->to);
$node2 = mysql_fetch_object($node2);
$tag2 = $node2->tags;
mysql_query('UPDATE nodes SET tags="'.$tag1.$res->tags.'" WHERE nodes.id='.$res->from);
mysql_query('UPDATE nodes SET tags="'.$tag2.$res->tags.'" WHERE nodes.id='.$res->to);`
Nohup 每 55-60 秒显示一次 'echo "$i\n"' 的输出(如果 'edges' 表的大小超过 9,000,000 行,就像我的情况一样,这可能需要 17 年以上才能完成)。
Htop 显示了一个占用 40-60% CPU 的 /usr/bin/mysqld 进程。
尝试计算边的权重(距离)的脚本存在相同的问题(选择所有边,取一条边,然后从“节点”表中选择该边的两个节点,然后计算距离,然后更新边表)。
问题:
如何使此 SQL 更新更快?我应该调整任何 MySQL 配置设置吗?或者我应该将 PostgreSQL 与 PostGIS 扩展一起使用?我应该为我的数据使用另一种结构吗?或者我应该以某种方式利用空间索引?