4

I have a table of locations that users of my app need to be able to search in. Baically "locations within x miles of me"

I'm using a query like this:

select * from job_locations 
   where earth_box(ll_to_earth(51.5, -0.085), 5000) @> ll_to_earth(latitude, longitude)  
   and earth_distance(ll_to_earth(51.5, -0.085), ll_to_earth(latitude, longitude)) < 5000;

And an index like this:

CREATE INDEX job_locations_lat_lng on job_locations USING gist(ll_to_earth(latitude, longitude));

However, this is a multi-tenant system, where all tables have a "tenant_id" field, and we always filter by that too. So ideally, I'd be able to have both tenant_id and ll_to_earth(lat, lng) in the index, which should presumably make searching much faster.

Is this possible? How do I create that index?

Thanks!
Daniel

Daniel Magliola
  • 30,898
  • 61
  • 164
  • 243

1 Answers1

6

You will probably need the btree_gist extension to create the index to include the tenant_id field, which appears to have existed since at least Postgres 8,.4.

CREATE EXTENSION btree_gist;
CREATE INDEX job_locations_lat_lng ON job_locations USING gist(tenant_id, ll_to_earth(latitude, longitude));
bma
  • 9,424
  • 2
  • 33
  • 22
  • Excellent, adding that extension fixed the problem. Thank you!! – Daniel Magliola Aug 05 '13 at 14:42
  • Quick question, is `gist(ll_to_earth()` a spatial index or a generic index of postgres? – Morteza Shahriari Nia May 27 '15 at 11:40
  • 1
    "ll_to_earth()" is part of the "earthdistance" module, see http://www.postgresql.org/docs/current/static/earthdistance.html. "gist" is an index type in core PostgreSQL, see http://www.postgresql.org/docs/current/static/textsearch-indexes.html – bma May 27 '15 at 14:07