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的查询。
答案 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