MySQL“OR MATCH”在多个表上挂起(非常慢)

时间:2010-05-23 08:03:11

标签: mysql full-text-search

在学习了如何进行MySQL全文搜索之后,多个表的推荐解决方案是OR MATCH,然后执行其他数据库调用。您可以在我的查询中看到。

当我这样做时,它只是陷入“忙”状态,我无法访问MySQL数据库。

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 ( SELECT `product_id`, `image`, `swatch` FROM `product_images` WHERE `sequence` = 0) 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 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 

非常感谢任何帮助。


修改

所涉及的所有表格都是MyISAM,utf8_general_ci。

这是EXPLAIN SELECT语句:

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY a ALL NULL NULL NULL NULL 16076 Using temporary; Using filesort
1 PRIMARY b ref product_id product_id 4 database.a.product_id 2  
1 PRIMARY e eq_ref PRIMARY PRIMARY 4 database.a.industry_id 1  
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 23261  
1 PRIMARY d eq_ref PRIMARY PRIMARY 4 database.a.brand_id 1 Using where
2 DERIVED product_images ALL NULL NULL NULL NULL 25933 Using where

我不知道如何让它看起来更整洁 - 抱歉


更新

它在196秒后返回查询(我认为正确)。没有多个表的查询大概需要0.56秒(我知道这很慢,我们计划很快改成solr或sphinx),但是196秒?

如果我们可以在相关性中添加一个数字(如果它在品牌名称中(d。name),那么它也可以使用

1 个答案:

答案 0 :(得分:4)

我发现有两件事情大大减慢了我的查询并修复了它们。

要回答第一个问题,它需要围绕整个“对抗或对抗的比赛”括号:

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 )
    )

我不明白如何使用EXPLAIN SELECT,但它帮助了很多,谢谢!这将第一个数字16076行减少到143.然后我注意到另外两个行超过23和25,000行。这是因为这一行:

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

我有一个原因,我首先这样做,然后改变了。当我改变它时,我没有意识到我可以做一个正常的LEFT JOIN

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

这使得我的最终查询如下:(并且更快从196秒变为0.0084左右)

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

哦,甚至在我用多个表进行全文搜索之前,它大概需要1/2秒。这有很大改善。