Opened 11 years ago

Closed 11 years ago

#21346 closed Bug (invalid)

GeoDjango query repeatedly executed in loop

Reported by: django@… Owned by: nobody
Component: GIS Version: 1.5
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm running Django 1.5.5 on OSX 10.7.5 with Python 2.7.5 and PostgreSQL 9.3.1 and PostGIS version 2.1.0"

"POSTGIS="2.1.0 r11822" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.10.1, released 2013/08/26" LIBXML="2.9.1" LIBJSON="UNKNOWN" TOPOLOGY RASTER"

I've discovered what appears to be a bug causing GeoDjango queries to be repeatedly executed. What I'm doing here is seeing what locations touch other locations. In this specific example, I'm querying France. My database is populated from the Natural Earth dataset.

print datetime.datetime.now()
touching_locations = Location.objects.filter(geometry__touches=Location.objects.get(name='France').geometry).values_list('name', flat=True)
print type(touching_locations)
for i in range(10):
    print datetime.datetime.now(), touching_locations
print datetime.datetime.now()

Output:

2013-10-28 16:09:14.958192
<class 'django.contrib.gis.db.models.query.GeoValuesListQuerySet'>
2013-10-28 16:09:14.974053 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:09:22.576670 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:09:30.089413 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:09:37.616438 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:09:45.119495 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:09:52.664080 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:10:00.197783 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:10:07.730839 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:10:15.270071 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:10:22.898417 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:10:30.429394

So, you can see that there's about 8 seconds between print statements. This is obviously because it's repeatedly executing the query. Now, if I force the query to be stored in a list, I see the performance I expect:

print datetime.datetime.now()
touching_locations = [x for x in Location.objects.filter(geometry__touches=Location.objects.get(name='France').geometry).values_list('name', flat=True)]
print type(touching_locations)
for i in range(10):
    print datetime.datetime.now(), touching_locations
print datetime.datetime.now()
2013-10-28 16:11:58.997853
<type 'list'>
2013-10-28 16:12:06.539672 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539702 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539714 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539724 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539734 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539744 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539755 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539765 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539775 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539784 [u'Belgium', u'Brazil', u'Germany', u'Spain', u'Italy']
2013-10-28 16:12:06.539804

Now, you can see that the query is just called once, and performance is much better.

Change History (1)

comment:1 by Tim Graham, 11 years ago

Resolution: invalid
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top