Python GeoDjango触摸功能运行缓慢

Python GeoDjango触摸功能运行缓慢,python,django,postgresql,postgis,geodjango,Python,Django,Postgresql,Postgis,Geodjango,首先,这是我的设置: Python 2.7.6 Django 1.6 PostgreSQL 9.3.1 PostGIS 2.1.1 我已将自然地球和数据集加载到PostGIS中。以下是我使用的Django模型: class Location(models.Model): name = models.CharField(max_length=255) imported_from = models.CharField(max_length=255) admin_level

首先,这是我的设置:

  • Python 2.7.6
  • Django 1.6
  • PostgreSQL 9.3.1
  • PostGIS 2.1.1
我已将自然地球和数据集加载到PostGIS中。以下是我使用的Django模型:

class Location(models.Model):
    name = models.CharField(max_length=255)
    imported_from = models.CharField(max_length=255)
    admin_level = models.CharField(max_length=255, blank=True)
    geometry = models.MultiPolygonField(blank=True, default=None, null=True)
    objects = models.GeoManager() #override the default manager with a GeoManager instance
    parent = models.ForeignKey('self', blank=True, default=None, null=True)

    def __unicode__(self):
            return self.name

    @staticmethod
    def get_countries(continent):
            return Location.objects.filter(parent=continent).order_by('name')

    @staticmethod
    def get_continents():
            return Location.objects.filter(parent=None).order_by('name')

    @staticmethod
    def get_states(country):
            return Location.objects.filter(parent=country).order_by('name')
这应该是不言自明的,但需要注意的一点是,这允许一个位置层次(例如,德克萨斯州在美国,而它在北美)

我需要得到一组与其他位置接触的位置。以下是我在视图中的操作方式:

touching_locations = {x for x in Location.objects.filter(geometry__touches=Location.objects.get(name='LOCATION_NAME').geometry).values_list('name', flat=True)}
这个查询在某些地方(如安哥拉)运行得很好,但在其他一些地方(如美国)运行得非常慢。我确实在
几何体上创建了一个要点索引,但我没有看到我预期的速度。当我为美国运行查询时,django调试工具栏告诉我查询()需要106260.14毫秒才能完成,这显然是不可接受的


整个位置表只有4865个条目,那么发生了什么?我发出这个查询对吗?

是的,我希望它会很慢,因为您链接到的几何体非常大:

[[ MULTIPOLYGON - 346 elements, 36054 pts ]]
要点索引也不会有帮助,因为CPU会消耗大量时间来确定该点是否在这个特定的详细多边形内,而不是确定它是否在包含数千行数据的边界框(bbox)内。请注意,这是几何图形和一个重叠在几个大陆上的bbox:

由于bbox在带有+ve经度的日期线上弯曲,它覆盖了欧洲。这意味着,如果在欧洲查询一个点,它将与美国的bbox相交,PostGIS可能需要检查这个大型几何体,以查看它是否与多边形接触。请参阅以了解GiST索引的工作原理,以及为什么重叠较少的较小框查询速度最快


最好的解决方案是使用较小的几何图形,这些几何图形本身具有较少的元素/点,并且通常具有较小的BBox以帮助编制GiST索引。您提到的“状态”数据集更理想,因为它们的地理范围有限,顶点可能更少(有助于详细的空间关系查询)。除了自然地球之外,确定全球行政边界的一个非常好的数据集是:


这两个选项都会移动边界并改变“接触”的含义,因为边界不同,这会对“接触”产生巨大的影响。请注意,还有几个更常见的运算符,它们表示不同的内容,例如“相交”、“包含”和“内部”;请看

这是一个非常好的解释,完全不是我所期望的。另一个解决方案是,我们可以简单地修剪夏威夷/阿拉斯加的外部点,使bbox更小。如果我们去美国的数据集,这个问题实际上不会得到解决,因为夏威夷/阿拉斯加的bbox仍然会环绕。