我已经为相同的操作编写了这两个查询,基于时间复杂度,我想知道哪个是有效的。
select Fname, Lname, Address
from (select * from department d, employee e where d.Dnumber = e.Dno) as a
where a.Dname = 'Research';
编辑:根据我的第一条评论,我假设 from 子句中的查询将用作临时表/视图,我将其命名为“a”,并包含两个表的所有列,我使用它。(我不我不知道这是一种有效的方法。)
或者
select Fname, Lname, Address from employee
where Dno = (select Dnumber from department where Dname = 'Research');
或者可以有更有效的方法来做到这一点。谢谢。
编辑2:
SELECT Pnumber, Dnum, Lname, Address, Bdate
FROM employee
JOIN department d ON d.Mgr_ssn = employee.Ssn
JOIN project p ON p.Dnum = d.Dnumber
WHERE p.Plocation = 'Stafford';
我有这个论点,你能告诉我这有什么缺陷吗?
让我们在每个 PROJECT、DEPARTMENT、EMPLOYEE 表中有 1000 行,
然后在上面的查询中,编译器将选择必须以什么顺序应用连接(ABC、ACB、BCA、BAC,...)选择有效的一个。但是要为第一个选择最好的,然后第二个,......它必须执行所有并相互比较,加上之后所涉及的元组的顺序将是相同的(不确定,也许如果它适用员工,部门首先它只有 100-150 行,这完全取决于表......对吗???)。我从来没有处理过实时项目情况,也许 JOINS 有一些我看不到的优势(这就是它提前发布的原因)。但我不相信。
然后在下面的查询中让 250 成功,然后 CARTESIAN PRODUCT 与 DEPARTMENT 表产生 2,50,000 个元组,假设 5,000 是 RESULT,然后再次使用 CARTESIAN PRODUCT 与 1000 个元组产生 500,000。
SELECT Pnumber, Dnum, Lname, Address, Bdate
FROM (SELECT Pnumber, Dnum, Mgr_ssn
FROM department d, (SELECT Pnumber, Dnum
FROM project where Plocation = 'Stafford') p
WHERE d.Dnumber = p.Dnum) q, employee e
WHERE q.Mgr_ssn = e.Ssn;
所以,我的问题是 JOIN 是简单地编写查询,让编译器决定什么是有效的顺序。而在下面的内容中,我们几乎完成了编译器的工作。
而且,我还有一个问题,WHERE 子句仅适用于一个关系?或者让我改写一下,首先执行 FROM(连同所有 JOINS)子句,然后执行 where 子句,因为在这种情况下,使用 JOINS 的查询将非常昂贵.
谢谢。
你也可以写
这相当于查询二并且可以是更清晰的形式(请参阅https://stackoverflow.com/questions/1599050/ansi-vs-non-ansi-sql-join-syntax以获得描述为什么首选较新语法的答案). 大多数查询优化器会看到这种等价性,并为这样一个简单的查询执行相同的操作,但对于更复杂的查询,情况可能并非如此(如果存在差异,
JOIN
变体可能是两者中更好的)。并不是说这几乎等同于您的第一个查询的内部部分,您使用的连接语法是旧的但等效的。当您在内部查询中执行此操作时,只需在外部查询中添加一个额外的过滤器,一个好的查询规划器会将这些查询视为相同的,并以完全相同的方式运行它们。一个糟糕的查询规划器会让引擎首先运行内部查询,然后应用额外的过滤子句,这使得它的效率大大降低,具体取决于它使用的索引。
但这一切都取决于您应该编辑问题和标签以提供的一些内容:
此外,大多数数据库引擎都提供了一种方法来读取查询计划器可能对给定查询执行的操作,哪种情况有助于判断哪个选项是最佳的——我不会在我知道的每个数据库中列出如何做到这一点,是具体说明您正在使用的数据库,我们可以更具体和相关地提供我们给出的答案。
请注意,如果您运行第二个查询并且其中有两行
department
,name='Research'
那么您可能会收到错误消息,因为=
运算符每一侧只能处理一个值。要列出所有部门中具有该名称的人员,请IN
改用。这可能会改变最有效的答案。