用作 EXISTS 子查询时查询速度较慢

发布于 2024-12-07 22:05:21 字数 479 浏览 0 评论 0原文

我有以下查询:

SELECT I.InsuranceID
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28

它大约在一秒钟内执行。当用作子查询时如下:

IF EXISTS(
SELECT I.InsuranceID
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28
)
SELECT 1
ELSE
SELECT 0

需要 90 秒。据我了解, EXISTS 应该优化为在找到第一条记录后停止。为什么这需要更长的时间?

I have the following query:

SELECT I.InsuranceID
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28

It executes in about a second. When used as a subquery as follows:

IF EXISTS(
SELECT I.InsuranceID
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28
)
SELECT 1
ELSE
SELECT 0

It takes 90 seconds. It's my understanding that EXISTS is supposed to be optimized to stop after finding the first record. Why would this take longer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

星軌x 2024-12-14 22:05:21

我自己也见过这个。

我可以猜测 EXISTS 在 WHERE 子句中更好,因为它提供了基于集合的半连接,并且正是您所需要的。

在 IF 中,优化器并不清楚这一点。也就是说,也没有什么可以半连接的。希望这应该是相同的(这是不好的):

SELECT 1 WHERE EXISTS (SELECT I.InsuranceID
    FROM Insurance I
    INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
    WHERE I.InsuranceLookupID IS NULL
    AND JD.JobID = 28)

尽管你可以这样做

SELECT SIGN(COUNT(*))
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28

它在某些情况下进行了优化:
什么是最好检查项目是否存在:选择 Count(ID)OR Exist(...)?

不确定是什么让优化器感到困惑...

I've seen this myself.

I can guess that EXISTS is better in a WHERE clause because it gives a semi-join which is set based, And exactly what you need.

In an IF, this isn't clear to the optimiser. That is, there is nothing to semi-join too. This should hopefully be the same (bad that is):

SELECT 1 WHERE EXISTS (SELECT I.InsuranceID
    FROM Insurance I
    INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
    WHERE I.InsuranceLookupID IS NULL
    AND JD.JobID = 28)

You could to this though

SELECT SIGN(COUNT(*))
FROM Insurance I
INNER JOIN JobDetail JD ON I.AccountID = JD.AccountID
WHERE I.InsuranceLookupID IS NULL
AND JD.JobID = 28

It is optimised in some circumstances:
What's the best to check if item exist or not: Select Count(ID)OR Exist(...)?

Not sure what confuses the optimiser...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文