Nope. in either case the "burden" is on the server, not the client accessing the page. The only way to move the burden to the client accessing the page would be retrieving coding in javascript something that is capable to get distinct values from a set, but you'd still be forced to transmit over the wire the entire 1M rows set. Of course that would be slow/counterproductive.
You were saying that select() and select(distinct) generates the same query and the "burden" of distinct-ing the values was on web2py. That is not true. select() and select(distinct=...) generates different queries, but the processing of the "distinct-ion" is on the server, but it's on the database application, not on web2py. if it was on web2py, the db application should have been forced to send 1M rows to web2py, and web2py needed to cycle all the 1M set to get the different values. This is not true. The db application, when select(distinct=..) is called generates only the set of distinct values (let's say, 100 distinct values). It's safe to assume that dbs are much faster than python to do that kind of work, because they are engineered/optimized for that kind of work (some dbs are developed from more than 15 years) . That being said, using an index on the table field you are using as distinct can speedup the retrieval even further because the db is not forced to physically read 1M rows, but it can scan the (supposedly less large) index. In the case that on a 1M rows your distinct values are 100, the index would be ~10000 times smaller than the table. --