How efficient is it to order by distance (entire table) in geodjango

前端 未结 1 465
借酒劲吻你
借酒劲吻你 2021-01-14 14:20

Assume that I have the following data model

Person(models.Model):
    id       = models.BigAutoField(primary_key=True)
    name     = models.CharField(max_le         


        
相关标签:
1条回答
  • 2021-01-14 15:01

    If you want to sort every entry on that table by distance then it will be slow as expected and there is nothing that can be done (that I am aware of at this point of time and my knowledge.)!

    You can make your calculation more efficient by following this steps and making some assumptions:

    1. Enable spatial indexing on your tables. To do that in GeoDjango, follow the doc instructions and fit them to your model:

      Note

      In PostGIS, ST_Distance_Sphere does not limit the geometry types geographic distance queries are performed with. [4] However, these queries may take a long time, as great-circle distances must be calculated on the fly for every row in the query. This is because the spatial index on traditional geometry fields cannot be used.

      For much better performance on WGS84 distance queries, consider using geography columns in your database instead because they are able to use their spatial index in distance queries. You can tell GeoDjango to use a geography column by setting geography=True in your field definition.

    2. Now you can narrow down your query with some logical constrains:

      Ex: My user will not look for people more than 50km from his current position.

    3. Narrow down the search using dwithin spatial lookup which utilizes the above mentioned spatial indexing, therefore it is pretty fast.

    4. Finally apply the distance order by on the remaining rows.

    The final query can look like this:

    current_location = me.location
    people = People.objects.filter(
        location__dwithin=(current_location, D(km=50))
    ).annotate(
        distance=Distance('location', current_location)
    ).order_by('distance')
    

    P.S: Rather than creating a custom pagination attempt, it is more efficient to utilize the pagination methods provided for the django views:

    • Docs

    Or you can use Django Rest Framework and use it's pagination:

    • Docs and a DRF pagination Q&A example
    0 讨论(0)
提交回复
热议问题