Recently i got a complaint from our hoster about a query taking as long as 2 seconds

It was actually easy to reproduce on my local workstation so i was able to track down the cause. The query is created by the advanced_search_result where a price-range is given (with display price with tax set to true). Query becomes as follows (for vanilla 2.2rc2 installation):
select distinct p.products_image, m.manufacturers_id, p.products_id, pd.products_name, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price , SUM(tr.tax_rate) as tax_rate from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id left join tax_rates tr on p.products_tax_class_id = tr.tax_class_id left join zones_to_geo_zones gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '223') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '18'), products_description pd, categories c, products_to_categories p2c where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '1' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id and (IF(s.status, s.specials_new_products_price, p.products_price) * if(gz.geo_zone_id is null, 1, 1 + (tr.tax_rate / 100) ) >= 50) and (IF(s.status, s.specials_new_products_price, p.products_price) * if(gz.geo_zone_id is null, 1, 1 + (tr.tax_rate / 100) ) <= 250) group by p.products_id, tr.tax_priority order by pd.products_name limit 0, 20;
This query takes about 2 seconds on our database with +/- 2500 products. Notice that i extended the query a lot but i will leave the details out for now since i don't think it adds anything to the issue at hand.
When i simply remove the last two if statements query becomes as shown below and it takes only 60ms.
select distinct p.products_image, m.manufacturers_id, p.products_id, pd.products_name, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price , SUM(tr.tax_rate) as tax_rate from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id left join tax_rates tr on p.products_tax_class_id = tr.tax_class_id left join zones_to_geo_zones gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '223') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '18'), products_description pd, categories c, products_to_categories p2c where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '1' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id and (IF(s.status, s.specials_new_products_price, p.products_price) * (1 + (tr.tax_rate / 100) ) >= 50) and (IF(s.status, s.specials_new_products_price, p.products_price) * (1 + (tr.tax_rate / 100) ) <= 250) group by p.products_id, tr.tax_priority order by pd.products_name limit 0, 20;
I allready tried to add some indexes on tr and gz but that only helps slightly (going down to 1.4 seconds).
I'm having difficulties to optimize the query, is there a common solution to this? What alternatives do i have for the if - condition?
Paul