2013-07-09 36 views
-2

我有一个要求,以显示商品详细页的同类产品以这样的方式,上市的产品应低于如何使用多个select查询优化一个UNION mysql查询?

  1. 大小,颜色,类别,公司给出的分级方式符合目前产品性能应与当前的产品
  2. 大小,颜色,类别应与当前的产品
  3. 大小,颜色应与当前的产品
  4. 大小应与当前的产品
如下面给出

我的SQL查询:

(SELECT pd.product_id, pd.name, p.price 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.category_id = '3' AND 
      pd.company_id = '1' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
      ORDER BY RAND() LIMIT 10 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.category_id = '3' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
      ORDER BY RAND() LIMIT 10 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
      ORDER BY RAND() LIMIT 10 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
      ORDER BY RAND() LIMIT 10 
    ) 

53 - 当前的产品ID和状态表示可用!

有没有什么办法来优化上述查询?

注输出要求:我们需要10个相似的产品。如果存在4个匹配条件1的产品,则需要先按随机顺序列出。同样,我们需要列出与其下面的其他条件匹配的产品。

在此先感谢!

+1

ORDER BY RAND()一般是缓慢的,反正你需要提供解释的输出。 –

+0

感谢您的评论。我已经更新了这个问题。 –

+0

对不清楚,但我在说,http://dev.mysql.com/doc/refman/5.0/en/explain.html –

回答

1

保持使用ORDER BY RAND()(这是不高效的),那么一个非常基本的改进就是为每个子句添加一个优先级,将order子句移动到最后,因此只需要一次。

(SELECT pd.product_id, pd.name, p.price , 1 AS recpriority 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.category_id = '3' AND 
      pd.company_id = '1' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price , 2 AS recpriority 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.category_id = '3' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price , 3 AS recpriority 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.color_id = '2' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
    ) 
     UNION 
    (SELECT pd.product_id, pd.name, p.price , 4 AS recpriority 
     FROM mg_product_description pd 
      JOIN `mg_product` p ON p.product_id = pd.product_id 
     WHERE 
      pd.size_id = '33' AND 
      pd.product_id != '53' AND 
      p.status = '1' 
    ) 
    ORDER BY recpriority, RAND() LIMIT 10 

这可能再被做这样的事情,而不需要做的工会: -

SELECT pd.product_id, 
    pd.name, 
    p.price , 
    CASE 
     WHEN pd.color_id = '2' AND pd.category_id = '3' AND pd.company_id = '1' THEN 1 
     WHEN pd.color_id = '2' AND pd.category_id = '3' THEN 2 
     WHEN pd.color_id = '2' THEN 3 
     ELSE 4 
    END AS recpriority 
FROM mg_product_description pd 
JOIN `mg_product` p ON p.product_id = pd.product_id 
WHERE pd.size_id = '33' 
AND pd.product_id != '53' 
AND p.status = '1' 
ORDER BY recpriority, RAND() 
LIMIT 10 
+0

太棒了!非常感谢 :) !是否有任何其他方式来选择随机行(...使用ORDER BY RAND()(这是不高效的)...)? –

+0

是的。我已经使用了更有效的方法返回单行(实质上,您可以在最小和最大ID之间获得一个随机值,然后选择该随机值之上的第一个ID),但不确定当您检索10时是否可以使用该值。这篇文章可能对你确定一个好的随机方法有用 - http://stackoverflow.com/questions/4329396/mysql-select-10-random-rows-from-600k-rows-fast – Kickstart

+0

谢谢Kickstart! –