SELECT много много полей price AS prize, IF(id, 1, 0) AS rice_exists ,manager,idh,himg_src
FROM `vahvah` AS `h`
JOIN (
SELECT id
FROM `vahvah`
WHERE `city`=777 AND `tus` = "active" AND `blocked` = 0
AND (`rice` IS NOT NULL AND `rice` > 0)
) AS h2 USING (id)
LEFT JOIN `zvezdi` AS `co` ON `co`.`co`=`h`.`h`
LEFT JOIN `nebo` AS `ci` ON `ci`.`ci`=`h`.`h`
LEFT JOIN `hom` hm ON hm.l=h.l_id
LEFT JOIN `hots` si ON si.hot=h.hot_id
LEFT JOIN `hoions` exh ON exh.l=h.l_id
LEFT JOIN `horts` air ON air.l=h.l_id
LEFT JOIN `howays` ra ON ra.h=h.l_id
LEFT JOIN `geo_jects` hge ON hge.id=h.h_id
LEFT JOIN `prices` `p` ON `h`.`hotel_id`=`p`.`l_id` AND p.`from`=12.12.2999 AND p.`to`=12.12.2999
Предлагаю тюнингнуть запрос немного, без изменений архитектуры бд. Смысл вот в чем: сначала выбираем нужные айдишники по условию (с индексами), затем джойним остальное к только найденым. В вашем примере джойн будет по всем полям, пока не найдет нужное. условие. Т.е. если данные берутся с главной таблицы ("vahvah") из конца то произойдет проверка всей таблицы вместе с джойнами, а это 9 вложенных циклов мускуля на каждую запись.
`tus` = "active" я бы сделал численным (или булевым, если статус бинарный) параметром, а не строковым. Но это уже мелкий тюнинг самой бд врятли сильно поможет, но все же =)
П.С.
Это примерный набросок, может не работать, но мысль думаю понятна.