Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL OR MATCH se bloque (très lentement) sur plusieurs tables

J'ai trouvé 2 choses qui ralentissaient considérablement ma requête et je les ai corrigées.

Pour répondre au premier problème, il fallait des parenthèses autour de l'ensemble "MATCH CONTRE OU MATCH CONTRE":

WHERE 
    b.`website_id` = %d
    AND b.`status` = %d
    AND b.`active` = %d 
    AND ( 
        MATCH( a.`name`, a.`sku`, a.`description` ) AGAINST ( '%s' IN BOOLEAN MODE ) 
        OR MATCH ( d.`name` ) AGAINST ( '%s' IN BOOLEAN MODE )
    )

Je n'ai pas compris comment utiliser EXPLAIN SELECT , mais ça m'a beaucoup aidé, alors merci ! Cela a réduit ce premier nombre de 16 076 lignes à 143. J'ai ensuite remarqué les deux autres avec plus de 23 et 25 000 lignes. C'était à cause de cette ligne :

LEFT JOIN ( SELECT `product_id`, `image`, `swatch` FROM `product_images` WHERE `sequence` = 0) AS c 
    ON (a.`product_id` = c.`product_id`)

Il y avait une raison pour laquelle je faisais cela en premier lieu, qui a ensuite changé. Quand je l'ai changé, je ne savais pas que je pouvais faire un LEFT JOIN normal :

LEFT JOIN `product_images` AS c 
    ON (a.`product_id` = c.`product_id`)

Cela rend ma requête finale comme ceci :(et BEAUCOUP plus rapide est passé de 196 secondes à 0,0084 environ)

SELECT 
    a.`product_id`, a.`name`, a.`slug`, a.`description`, b.`list_price`, b.`price`, 
    c.`image`, c.`swatch`, e.`name` AS industry, 
    MATCH( a.`name`, a.`sku`, a.`description` ) AGAINST ( '%s' IN BOOLEAN MODE ) AS relevance 
FROM 
    `products` AS a LEFT JOIN `website_products` AS b 
        ON (a.`product_id` = b.`product_id`) 
    LEFT JOIN `product_images` AS c 
        ON (a.`product_id` = c.`product_id`) 
    LEFT JOIN `brands` AS d 
        ON (a.`brand_id` = d.`brand_id`) 
    INNER JOIN `industries` AS e 
        ON (a.`industry_id` = e.`industry_id`) 
WHERE 
    b.`website_id` = %d
    AND b.`status` = %d
    AND b.`active` = %d
    AND c.`sequence` = %d
    AND ( 
        MATCH( a.`name`, a.`sku`, a.`description` ) AGAINST ( '%s' IN BOOLEAN MODE ) 
        OR MATCH( d.`name` ) AGAINST( '%s' IN BOOLEAN MODE ) 
    )
GROUP BY a.`product_id` 
ORDER BY relevance DESC 
LIMIT 0, 9

Oh, et même avant de faire une recherche en texte intégral avec plusieurs tables, cela prenait environ 1/2 seconde. C'est bien amélioré.