Optimising a query with two aggregate fields
What database?  Does your database support row_number(). 

And you changed the query.  In the first max(scanTime), max(scanId) are not necessarily on the same row.  Those are two independent max.  

The scanTime of the row with the max(scanID) is different and what you got with the second.  It is faster as scanID is indexed (PK) and scanTime is not. Since scanID is the PK you don't need:  

AND q.regionId = sq.regionId AND q.typeId=sq.typeId


If your database supports row_number()

select * from 
(
SELECT scanTime, mscanId, typeId, regionId  
     , row_number over (partition by typeId, regionId order by mscanId desc) rn
FROM scanTimes 
) tt
where tt.rn = 1