Slow query issues with search box

We have an oscommerce website and have been experiencing some slow performance intermittently. I browsed through the slow query log and found a whole bunch of the following:

Query_time: 86 Lock_time: 0 Rows_sent: 1 Rows_examined: 13424559

select count(distinct p.products_id) as total from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id, 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 ((pd.products_name like ‘%x%’ or p.products_model like ‘%x%’ or m.manufacturers_name like ‘%x%’ or pd.products_description like ‘%x%’) );

It appears that someone or a bot is repeatedly hitting our search box with a search for “x” which is bogging our site down by examining 13M rows each time. Is there a way to write that query to quit after ~200 results have been found? I suppose we could filter the search values in php, but it would be better to build it into the query…

i think some of the problem might just lie in how the query is written

the tipoff is COUNT DISTINCT – this will return a result, but the use of DISTINCT is often a sign of underlying problems, such as a query which has cross join effects

in order to understand your scenario, i took the liberty of re-formatting it so that an analysis of what it’s doing can more easily be effected

you should strive to incorporate formatting into your queries as well

SELECT COUNT(DISTINCT p.products_id) AS total 
  FROM products p 
LEFT 
  JOIN manufacturers m 
 USING (manufacturers_id) 
LEFT 
  JOIN specials s 
    ON p.products_id = s.products_id

, 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 ( ( pd.products_name like '%x%' 
        or p.products_model like '%x%' 
        or m.manufacturers_name like '%x%' 
        or pd.products_description like '%x%'
       ) )

can i ask you why you are returning just a count? if this is a search query, aren’t you also going to, you know, return some products?