You've all seen those nifty searches which enable you to search for things near something else. A few years ago I was faced with this problem and tackled it the only way I know how, by cheating. Really, querying this isn't such a problem when your pool of available things isn't very big. I mean really, How many Chicken-Marts are there in the country? What happens when you need to search over, oh I don't know, let's say 10 million things. Well, ideally I would have has access to a spatially enabled database. Of course, if I did, then the story would have ended here.
The biggest time saver I was able to do was get everyone to agree that nobody really cares down to the street level if a location is 25 miles from a certain zip. You're already searching from the centroid of a zip as your focus point for the radius search. The distance we're showing isn't going to be exact, so we make it a little worse by only geocoding our destinations down to the zip code level. I just cut my possible search from 10 million to 40-something thousand. Nice. In case you are wondering, my zip coordinates table looks like this:
create table zip_coords( zip number, latitude number, longitude number );
I just did this one and this made a HUGE difference in the speed. Of course, this is at the expense of disk space. I precalculated the distances from one zip to every other zip within 150 miles. I wrote a little program that pulled in my zip_coords values and did a nested loop over them to calculate the distances and only spooled out those less than 150 miles. This gave me a 67 million row table which looks like this:
create table zip_radius_map( zip_from number, zip_to number, radius number );
Throw an index on this table and you are ready to faux-geo search with the quickness. Your radius search query is now as simple as:
select count(1) from records inner join addresses using(address_id) where zip in ( select zip_to from zip_radius_map where zip_from=:zip and radius < :radius )