Go with steps:
-Create spatial indexes for your tables.
-Create Buffers
CREATE OR REPLACE VIEW b1 as
SELECT ST_Buffer(the_geom,500) as the_geom, attributes, fid
FROM stores;
CREATE OR REPLACE VIEW b2 as
SELECT ST_Buffer(the_geom,2000) as the_geom, attributes, fid
FROM stores;
(I am not sure, but maybe you should reduce here you 8 million point to less whith a materialized view like this:
select a.point_attributes
from b2 b, spoints a
where st_within(a.the_geom, b.the_geom)
)
-Create ring view r2:
CREATE OR REPLACE VIEW r2 as
SELECT ff.fid, ff.attributes, ST_Difference(ff.the_geom, g.the_geom) as new_geom
FROM b2 ff
JOIN b1 g ON (g.fid= ff.fid)
GROUP BY ff.fid, ff.attrubets, g.the_geom, ff.the_geom;
-Select those rings where the altitude is bigger than 400 meters.
-And the slow bit the intersection:
SELECT ff.fid, ff.attributes FROM r2 ff
JOIN points_table g ON ST_Intersects(g.geom, ff.the_geom)
GROUP BY ff.fid, ff.attributes, ff.the_geom;