Sql 执行嵌套查询的次数
此嵌套子查询将执行多少次Sql 执行嵌套查询的次数,sql,database-agnostic,Sql,Database Agnostic,此嵌套子查询将执行多少次 SELECT CID, CNAME FROM CUSTOMER WHERE EXISTS ( SELECT CID FROM RENTALS WHERE CUSTOMER.CID = RENTALS.CID AND PICKUP = 'CARY' ) 这是一个理论问题,也就是说,它可以在我的书中找到。提供的答案是6,但我不明白为什么会这样 好的,
SELECT CID, CNAME
FROM CUSTOMER
WHERE EXISTS ( SELECT CID
FROM RENTALS
WHERE CUSTOMER.CID = RENTALS.CID
AND PICKUP = 'CARY' )
这是一个理论问题,也就是说,它可以在我的书中找到。提供的答案是6,但我不明白为什么会这样
好的,我认为这本书本身有一些问题。我会翻阅这本书,也许稍后会问这个问题。查询不会以这种方式执行。查询计划器将把它转换成这样的东西,它将针对另一个查询的结果运行一个查询,而不是反复运行子查询 查询的查询计划很可能与执行左联接并检查现有记录的查询的查询计划相同:
select c.CID, c.CNAME
from CUSTOMER c
left join RENTALS r on c.CID = r.CID and r.PICKUP = 'CARY'
where r.CID is not null
查询不会以这种方式执行。查询计划器将把它转换成这样的东西,它将针对另一个查询的结果运行一个查询,而不是反复运行子查询 查询的查询计划很可能与执行左联接并检查现有记录的查询的查询计划相同:
select c.CID, c.CNAME
from CUSTOMER c
left join RENTALS r on c.CID = r.CID and r.PICKUP = 'CARY'
where r.CID is not null
这个问题没有正确的理论答案。智能查询优化器可以将查询转换为联接:
SELECT CID, CNAME
FROM Customer
LEFT JOIN (SELECT DISTINCT CID FROM Rentals WHERE PICKUP = 'CARY') as Rentals
ON Customer.CID = Rentals.CID
WHERE Rentals.CID IS NOT NULL
现在子查询只执行一次。这个问题没有正确的理论答案。智能查询优化器可以将查询转换为联接:
SELECT CID, CNAME
FROM Customer
LEFT JOIN (SELECT DISTINCT CID FROM Rentals WHERE PICKUP = 'CARY') as Rentals
ON Customer.CID = Rentals.CID
WHERE Rentals.CID IS NOT NULL
现在子查询只执行一次。正如其他人所指出的,这个相关的子查询可以重写为联接,但这还不完全是问题的全部,因为未转换的EXISTS的执行计划看起来很像联接。所以这实际上不是一个语法问题,而是一个查询优化问题 EXISTS实际上只是“连接到此数据集,但即使有1000000个匹配项,也只连接到其中的一行”的语法简写,或者也被称为 因此,EXISTS谓词针对相关或不相关子查询所需的半连接可以通过多种方式实现,这在很大程度上取决于两个表中的数字或记录 如果您假设客户估计只有一行,而乐观主义者估计租金中有数千行皮卡=卡里,那么乐观主义者很可能从客户表中读取该行,并对租金表执行单个查找 如果估计有一百万个客户,并且RENTALS表中只有一行,那么该执行计划将是疯狂的——乐观主义者可以通过引导RENTALS表并对照CUSTOMER表查找要返回的单行来反转联接。在这种情况下,可以说根本没有执行子查询 在这两个极端之间,还有各种其他优化。例如,将RENTAL.CID列的唯一值构建到内存中的哈希表中,其中PICKUP='CARY'和full扫描CUSTOMER表以探测每一行的哈希表,这将是一个哈希半联接。同样,不执行可识别的子查询。(Barmer建议的查询重写可能会导致这种计划,但也可能会限制乐观主义者看到适合其他数据分布和基数的其他计划) 因此,正如其他答案所说,这个问题确实没有意义,因为我认为这里有两个重要的教训:
- 0
- 一,
- 然而,客户中有许多行
- 可能是别的