Hmm, this is not supposed to work at all in PostgreSQL as I understand it. The inner sub- select part of the query doesn't have access to the outer a_table. You can read about that on the bottom of this page. So if you don't get any error messages I guess the database tries to update in some strange way which might mean updating all rows.
What you should do here instead is:
UPDATE a_table
SET a.needed_value = b.wanted_value FROM b_table b
WHERE ST_Intersects(table.the_geom, b.the_geom);
You can not have an alias on a_table here.
I think it sounds strange that your question works at all so I might very well have missed something here.
But try my suggestion if that helps.
HTH
Nicklas
Update:
Ok Peter, you are of course right. I have actually avoided that construction because I have believed it would fail.
But I still think I have a point according to the issue it was all about. When I tried the query construction in the question it seems to behave a little odd. It seems to do a right join and update all records, not affected by the intersection test, with null-values. Maybe it is not a right join but the result seems to be the same. The output from the query is that all rows are affected.
That compared with "my" construction that does nothing with the point-records that doesn't intersect.
In this case when the point-table carries over 60 million rows I guess that might mean a significant difference in performance. Can that be the case?
EXPLAIN ANALYZE
output for the query.