2010-05-19 9 views
1

J'essaie d'optimiser la requête SQL listée ci-dessous.
Il s'agit essentiellement d'un code de moteur de recherche qui récupère les produits en fonction du nom du produit. Il vérifie également le numéro de modèle des produits et si oui ou non il est activé.
Cette exécute en environ 1,6 secondes lorsque je le lance directement à travers l'outil phpMyAdmin, mais prend environ 3 secondes au total pour charger conjointement avec le fichier PHP, il est placé.La requête SQL prend trop de temps

je besoin d'ajouter une fonctionnalité de recherche de catégorie et maintenant que cela plante le serveur MySQL, HELP!

Justin

SELECT DISTINCT 
    p.products_id, 
    p.products_image, 
    p.products_price, 
    s.specials_new_products_price, 
    p.products_weight, 
    p.products_unit_quantity, 
    pd.products_name, 
    pd.products_img_alt, 
    pd.products_affiliate_url 
FROM 
    products AS p 
    LEFT JOIN 
     vendors v 
    ON 
     v.vendors_id = p.vendors_id 
    LEFT JOIN 
     specials AS s 
    ON 
     s.products_id = p.products_id 
     AND 
     s.status = 1, 
    categories AS c, 
    products_description AS pd, 
    products_to_categories AS p2c 
WHERE 
    (
     (
      pd.products_name LIKE '%cleaning%' 
      AND 
      pd.products_name LIKE '%supplies%' 
     ) 
     OR 
     (
      p.products_model LIKE '%cleaning%' 
      AND 
      p.products_model LIKE '%supplies%' 
     ) 
     OR 
     p.products_id = 'cleaning supplies' 
     OR 
     v.vendors_prefix = 'cleaning supplies' 
     OR 
      CONCAT (CAST (v.vendors_prefix AS CHAR), '-', CAST (p.products_id AS CHAR)) = 'cleaning supplies' 
    ) 
    AND 
    p.products_status = '1' 
    AND 
    c.categories_status = '1' 
    AND 
    p.products_id = pd.products_id 
    AND 
    p2c.products_id = pd.products_id 
    AND 
    p2c.categories_id = c.categories_id 
ORDER BY 
    pd.products_name 
+4

Pouvez-vous poster la sortie de 'EXPLAIN your_query'? – richsage

+0

Combien de temps la requête prend-elle sans la partie de recherche? Est-ce la recherche ou les jointures qui ralentissent les choses? – jeroen

+0

Si vous avez plusieurs lignes, vous devez utiliser les index Mysql. Google à leur sujet, il peut rendre la requête beaucoup plus rapide. –

Répondre

3
left join specials as s on s.products_id = p.products_id and s.status = 1, 

là, vous avez un scan de table. Ce genre de données (tinyint, true/false) n'est pas bien géré par InnoDB. Dans Oracle, vous avez quelque chose comme un index bitmap, ce qui est bon pour les index de sélectivité faible. Vous pouvez utiliser un sous-requête, dans votre où, quelque chose comme ceci:

... 
where 
    p.product_id IN (SELECT S.status FROM specials s WHERE s.status = 1) 
AND 
    (
      (pd.products_name like '%cleaning%' and pd.products_name like '%supplies%') or 
... 

Ensuite, vous priez pour le cache de requête pour mettre en cache les résultats de cette sous-requête.

POSTALES EXPLIQUEZ!

0
select p.products_id, p.products_image, p.products_price, 
    p.products_weight, p.products_unit_quantity, 
    s.specials_new_products_price, 
    pd.products_name, pd.products_img_alt, pd.products_affiliate_url 
from products as p 
    left join vendors v ON v.vendors_id = p.vendors_id 
    left join specials as s on s.products_id = p.products_id, 
    left join products_description as pd on pd.products_id = p.products_id 
    left join products_to_categories as p2c on p2c.products_id = p.products_id 
    left join categories as c on c.categories_id = p2c.categories_id 
where 
     (
      (pd.products_name like '%cleaning%' and pd.products_name like '%supplies%') or 
      (p.products_model like '%cleaning%' and p.products_model like '%supplies%') or 
      p.products_id = 'cleaning supplies' or 
      v.vendors_prefix = 'cleaning supplies' or 
      CONCAT(CAST(v.vendors_prefix as char), '-', CAST(p.products_id as char)) = 'cleaning supplies' 
     ) 
    and p.products_status = '1' 
    and s.status = 1 
    and c.categories_status = '1' 
group by p.products_id 
order by pd.products_name 

Assurez-vous que vous avez les indices suivants fixés:

create index prod_prodid_status on products(products_id, products_status); 
create index vendors_vendorid on vendors(vendors_id); 
create index specials_prodid_status on vendors(products_id, `status`); 
create index prod_desc_prodid_prodname on products_description(products_id, products_name); 
create index prod_cat_prodid_catid on products_to_categories(products_id, categories_id); 
create index categories_catid_status on categories(categories_id, categories_status); 

Et j'espère que tous les champs avec « id » dans leur nom sont des entiers

Questions connexes