I managed to speed things up considerably by removing the reference to fsf2 in the query below, taken from one_file.tcl in the file-storage module. It is only referenced in the 'from' section of the query, causing a cartesian join.
select count ( fsv.version_id ) as n_versions,
fsf1.file_title,
fsf1.folder_p,
fsf1.parent_id,
fsvl.url,
u.first_names || ' ' || u.last_name as owner_name,
user_has_row_permission_p (3, 'read', fsvl.version_id, 'FS_VERSIONS' ) as public_read_p
from fs_files fsf1,
fs_files fsf2,
fs_versions fsv,
fs_versions_latest fsvl,
users u
where fsf1.file_id = 82
and fsvl.file_id = 82
and fsf1.file_id = fsvl.file_id
and user_has_row_permission_p (3, 'read', fsvl.version_id, 'FS_VERSIONS' ) = 't'
and fsf1.owner_id = u.user_id
group by fsf1.file_title,
fsf1.folder_p,
fsf1.parent_id,
fsvl.url,
u.first_names,
u.last_name,
user_has_row_permission_p (3, 'read', fsvl.version_id, 'FS_VERSIONS' )