JOINS而不是Sub-SELECT

时间:2013-12-30 16:29:36

标签: mysql sql join subquery

SUBSELECT的性能是否低于JOIN?

我收到了这个查询

SELECT   categories_id,
         products_id
FROM     products_to_categories a
WHERE    date_added = (
  SELECT MIN(date_added)
  FROM   products_to_categories b
  WHERE a.products_id = b.products_id
)
AND      categories_id != 0
GROUP BY products_id

并希望将其更改为使用JOIN的查询。

5 个答案:

答案 0 :(得分:1)

SELECT DISTINCT a.products_id,
         b.MinDate
FROM     products_to_categories a
JOIN     (SELECT b.products_id,
            MIN(b.date_added) AS MinDate
          FROM products_to_categories b
          GROUP BY b.products_id ) AS B
  ON     a.products_id = b.products_id
 AND     a.date_added = b.MinDate
WHERE    a.categories_id != 0

答案 1 :(得分:1)

  

SUBSELECT的性能是否低于JOIN?

可能。这完全取决于有问题的查询。许多经常使用子查询实现的构造(通过连接可以很容易地实现)实际上是由查询优化器在内部执行的...在具有企业级查询优化器的数据库系统中,如SQL Server和Oracle 。 MySQL的查询优化器在这些优化方面明显变差,您必须查看explain输出以查看它是否足够智能以适应您的特定情况。它甚至可以决定不应用这种优化,即使它看到它,只是因为系统负载足够低,优化将比执行较慢的版本慢。

即使它作为子查询执行,它也取决于查询本身和系统负载。子查询可能导致更快的锁升级,可能导致表锁,从而在同一个表上同时进行更多查询时执行速度变慢。如果没有并发性,额外的锁定不会导致明显的额外减速。

通常,尝试尽可能使用连接而不是子查询,但不要过度使用 - 子查询通常执行得非常好,查询优化器将很好地保持服务器活动。但是请记住,MySQL并不是一个“企业级RDBMS”,因此在优化方面可能相当愚蠢。

答案 2 :(得分:0)

在没有子查询或聚合的情况下将其切换为join并不明显。

我们的想法是在left outer join条件下使用条件执行date_added 。如果此条件匹配,则您具有最小值:

SELECT categories_id, products_id
FROM  products_to_categories a left outer join
      products_to_categories b
      on a.products_id = b.products_id and
         b.date_added < a.date_added
WHERE b.date_added is null and a.categories_id != 0;

答案 3 :(得分:-1)

是的,子查询更加过程密集,因为子查询周围的每个查询都需要等到子查询完成处理。加入时不一定是这种情况。

您是否需要有关Joins语法的帮助?或者我所需要的答案是什么?

以下是您要找的内容:

SELECT   a.categories_id,
         a.products_id
FROM     products_to_categories a
LEFT JOIN     products_to_categories b
  ON     a.products_id = b.products_id
WHERE    a.date_added = MIN(b.date_added)
  AND      a.categories_id != 0
GROUP BY a.products_id, a.categories_id

答案 4 :(得分:-1)

Select products_to_catergoriesa.categories_id, 
products_to_catergoriesa.products_id, min(products_to_categories b.date_added)

from products_to_categories a
join products_to_categories b 
on products_to_categories b.products_id = products_to_categories a.product_id

where [table_name_here].catergory_id !=0