如何将以下查询转换为内部联接,并避免使用distinct来优化性能。
select distinct(GroupId)
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and
GroupId not in
(
select distinct(groupid)
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and ObjectiveFunctionTotalResultID is null
)
GroupId不是主键。有多个行对应于单个GroupId。我想选择没有ObjectiveFunctionTotalResultID为null的GroupIds。 -
答案 0 :(得分:2)
首先,distinct不是函数,而是select语句的修饰符。您可以选择不同的字段值组合,而不是选择不同的单个字段。如果您有更多字段,则括号实际上会调用语法错误。所以它不是
select
distinct(groupid)
但
select distinct
groupid
其次,你根本不需要内在的区别。 in
列表中可能存在重复项,dbms可能已经为您优化了这一点。通过在内部查询中添加distinct
,您可以主动阻止优化器完成其工作。
第三,如果您想拥有不同的组ID,则仍需要distinct
外部查询。内部联接不会改变这一点。此外,由于您希望记录必须不匹配,因此内连接不会起作用。左连接可以执行此操作,但如果我正确解释您的查询,您可以将其写为:
select distinct
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
你可以将其改为group by
,就像我在下面所做的那样,但效果是一样的。分组只创建组,并且还必须删除重复项。分组主要用于聚合。我不确定内部工作原理,但group by在理论上是一个更难的过程,因为数据库需要为这些聚合创建实际的组,而不是仅仅过滤掉重复项。可能这也会被优化,所以最后,下面的查询将执行和行为与上面的相同。
select
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
group by
GroupId
答案 1 :(得分:2)
您可以使用LEFT JOIN
获得类似的结果,然后将联接结果设置为NULL
。
select distinct GroupId
from BatchQuotaIndividualQuotas A
left join BatchQuotaIndividualQuotas B ON B.ObjectiveFunctionTotalResultID IS NULL
AND B.GroupId = A.GroupId
AND B.BatchQuotaCommonSettingsID = 58
where A.BatchQuotaCommonSettingsID = 58
AND B.GroupId IS NULL
您也可以使用GROUP BY
和HAVING
获得相同的结果,但我怀疑这种方法会更快。
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
group by GroupId
having SUM(CASE WHEN ObjectiveFunctionTotalResultID IS NULL THEN 1 ELSE 0 END) = 0
答案 2 :(得分:1)
如果从where子句中删除distinct,则查询将运行得更快。
以下是两种更好的写作方式
count(ObjectiveFunctionTotalResultID)将计算非空值
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
GROUP BY GroupId
HAVING count(ObjectiveFunctionTotalResultID) = count(*)
或:
EXCEPT将包含不同的
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
EXCEPT
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
AND ObjectiveFunctionTotalResultID is null
答案 3 :(得分:0)
你能试试吗?
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and ObjectiveFunctionTotalResultID IS NOT NULL
GROUP BY GroupId
相同的查询(如果我是正确的)有一些修改后的流程。它不是通过子查询过滤掉ID,而是在适当的位置完成。