The query is only re-run if the SQL statement (the
... in
ns_db select $db "...") is the same. There are plenty of Tcl scripts in ACS/OpenACS that grab a handle, then execute multiple (different) queries. Often times the subsequent queries are based on data retrieved in the first.
The $selection ns_set holds different data with each call to ns_db getrow. If for some reason you want to preserve the ns_sets (and have, say, a list or array of ns_set's) then you'd need to do an ns_set copy $selection inside each while loop and lappend the newly copied set to a list (or stuff it inside an array or something).