You may want to investigate joining S_QOS_DATA (for machine name, QOS, and table_id) and S_QOS_SNAPSHOT (for the value)
Might be faster.
Regardless, that join should not have been that slow which would argue for an inadequately sized database server or a problem with how you are collecting your data - most likely the frequency at which you are collecting it.
And perhaps the query is in error:
You might want to try running:
select distinct s.source,d.dev_ip,s.probe,s.target,s.qos
from S_QOS_DATA s, CM_CONFIGURATION_ITEM_METRIC cim,CM_CONFIGURATION_ITEM ci,CM_DEVICE d,CM_COMPUTER_SYSTEM cs
where ( s.ci_metric_id=cim.ci_metric_id and cim.ci_id=ci.ci_id and ci.dev_id=d.dev_id and d.cs_id= cs.cs_id )
and s.qos in ( 'QOS_CPU_USAGE' , 'QOS_DISK_AVAILABLE' , 'QOS_MEMORY_PERC_USAGE')
order by source asc;
If that's too slow, drop the order by line.
And your ask was for the list of machines being monitored, which this is, but were you actually asking for the QoS current values for the systems being monitored?
-Garin