我有这样的事情:
SELECT CompanyId
FROM Company
WHERE CompanyId not in
(SELECT CompanyId
FROM Company
WHERE (IsPublic = 0) and CompanyId NOT IN
(SELECT ShoppingLike.WhichId
FROM Company
INNER JOIN
ShoppingLike ON Company.CompanyId = ShoppingLike.UserId
WHERE (ShoppingLike.IsWaiting = 0) AND
(ShoppingLike.ShoppingScoreTypeId = 2) AND
(ShoppingLike.UserId = 75)
)
)
它有3个选择,我想知道如何在不进行3次选择的情况下拥有它,哪一个拥有100万条记录的更快速度? "选择"或者"左连接"?
答案 0 :(得分:0)
我的经验来自Oracle。优化棘手的查询从来没有正确的答案,这是您和优化者之间的合作。您需要检查解释计划,有时还要检查跟踪,通常是在编写查询的每个阶段,以找出优化者的想法。话虽如此:
SELECT
... WHERE
中放置其子查询NOT(
子句的全部内容来删除外部)
。从表面上看,它将阻止公司的外部全面扫描(或它的CompanyId指数)。尝试一下,检查输出是否相同并获得时间,然后在尝试下面之前暂时将其删除。由于隐式OR被创建,NOT()
可能会导致优化器停止考虑针对ShoppingLike子查询的ANTI-JOIN。NOT NULL
列。如果没有这个(或类似于显式CompanyId IS NOT NULL
),则通常会丢弃ANTI-JOIN选项。INNER JOIN
,因为您希望ShoppingLike首先扫描,因为它具有针对它的所有过滤器。它不会有任何区别,但它读起来更容易,并且可以使用提示按指定的顺序扫描表。我甚至会质疑这个子查询中公司表的必要性。NOT IN
,有时非常相似NOT EXISTS
会为优化工具提供更多/替代选项。 除非您开始尝试解释计划,否则上述所有内容都只是反复试验。 Oracle可以随后在LEFT JOIN
和IN
SELECT
之间进行转换。 1M +行将创造投资时间。