我一直在通过简单的空间查询来测试几何图形并将其与Postgis进行比较。例如,此SQL查询在Postgis中运行30秒:
with series as (
select
generate_series(0, 5000) as i
),
points as (
select ST_Point(i, i*2) as geom from series
)
select st_distance(a.geom, b.geom) from points as a, points as b
现在,以下geomesa版本需要5分钟(使用-Xmx10g):
import org.apache.spark.sql.SparkSession
import org.locationtech.geomesa.spark.jts._
import org.locationtech.jts.geom._
object HelloWorld {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder
.config("spark.sql.crossJoin.enabled", "true")
.config("spark.executor.memory", "12g")
.config("spark.driver.memory", "12g")
.config("spark.cores.max", "4")
.master("local")
.appName("Geomesa")
.getOrCreate()
spark.withJTS
import spark.implicits._
val x = 0 until 5000
val y = for (i <- x) yield i*2
val coords = for ((i, n) <- x.zipWithIndex) yield (i, y(n))
val points = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
val points2 = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
val all_points = for {
i <- points
j <- points2} yield (i, j)
val df = all_points.toDF("point", "point2")
val df2 = df.withColumn("dist", st_distance($"point", $"point2"))
df2.show()
}
}
我期望Geomesa可以提供类似或更好的性能,如何调整这样的查询?
第一次编辑
正如Emilio建议的那样,这实际上不是查询,而是计算。 该查询本来可以毫无火花地编写。下面的代码在不到两秒钟的时间内运行:
import org.locationtech.jts.geom._
object HelloWorld {
def main(args: Array[String]): Unit = {
val x = 0 until 5000
val y = for (i <- x) yield i*2
val coords = for ((i, n) <- x.zipWithIndex) yield (i, y(n))
val points = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
val points2 = for {
i <- points
j <- points} yield i.distance(j)
println(points2.slice(0,30))
}
}
答案 0 :(得分:0)
对于少量数据,GeoMesa不会像PostGIS那样快。 GeoMesa专为分布式NoSQL数据库而设计。如果您的数据集适合PostGIS,则可能应该只使用PostGIS。一旦开始达到PostGIS的极限,就应该考虑使用GeoMesa。 GeoMesa确实提供了与任意GeoTools数据存储(包括PostGIS)的集成,这可以使PostGIS可以使用某些GeoMesa Spark和command-line功能。
对于您的特定代码段,我怀疑大部分时间都花在了RDD的旋转和循环运行上。实际上并没有一个“查询”,因为您只是在运行成对计算。如果要查询存储在表中的数据,则GeoMesa有机会优化扫描。但是,GeoMesa不是SQL数据库,也没有对连接的任何本机支持。通常,联接是由Spark在内存中完成的,尽管您可以执行一些操作来加快联接的速度(即broadcast join或RDD partitioning)。如果要进行复杂的空间连接,则可能需要查看专门从事空间Spark操作的GeoSpark和/或Magellan。