FROM suppliers c INNER JOIN supplier_site ss ON c.supplier_id = ss.supplier_id WHERE c.supplier_id != '0' AND ss.site_id = '2' GROUP BY c.supplier_id ORDER BY c.supplier_name ASC
Since auto-generated primary keys are never equal to 0 (if the design error is big db), you can refuse the c.supplier_id! = '0' clause.
ss.site_id = '2' must be in JOIN state for readability.
It looks like this should only match one row in the vend_site table for the vendor (if this is your usual thing-1-N-thing relationship, that is, you select the second address of each vendor, maybe “2” matches “billing address” or something- then), therefore GROUP BY c.supplier_id is useless.If GROUP BY is actually doing something, the query is incorrect, because the "address" columns that are supposedly coming from the supplier_site table will come from a random row.
So, here's a simplified OT (WHERE gone):
FROM suppliers c INNER JOIN supplier_site ss ON (c.supplier_id = ss.supplier_id AND ss.site_id = '2') ORDER BY c.supplier_name ASC
I assume you have an index on c.supplier_name, so this part of the query should be very fast.
Now try this query:
SELECT a.*, questapproved, ss.supplier_no AS supplier_no, IF (active=1,'Yes', IF (active=2, 'NCR Only','Inactive')) AS rated, sum( q.incomplete = '0') AS questions, sum( q.reviewed = '1' ) AS reviewed FROM ( SELECT c.supplier_id, supplier_name, address1, address2, address3, address4, suppliertype, postcode, contact_name FROM suppliers c INNER JOIN supplier_site ss ON (c.supplier_id = ss.supplier_id AND ss.site_id = '2') ORDER BY c.supplier_name ASC LIMIT 0, 20 ) a LEFT JOIN supplier_questions q ON (q.supplier_id = c.supplier_id) GROUP BY c.supplier_id ORDER BY c.supplier_name;