我在一个项目中,通过在FROM子句中包含多个表来执行大量查询。我知道这是合法的,但我总是使用显式的JOIN。
例如,两个表(使用SQL Server DDL)
CREATE TABLE Manufacturers(
ManufacturerID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
Name varchar(100))
CREATE TABLE Cars (
ModelID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
ManufacturerID INT CONSTRAINT FOREIGN KEY FK_Manufacturer REFERENCES Manufacturers(ManufacturerID),
ModelName VARCHAR(100))
如果我想找到GM的模型,我可以这样做:
SELECT ModelName FROM Cars c, Manufacturers m WHERE c.ManufacturerID=m.ManufacturerID AND m.Name='General Motors'
或
SELECT ModelName FROM Cars c INNER JOIN Manufacturers m ON c.ManufacturerID=m.ManufacturerID WHERE m.Name='General Motors'
我的问题是:一种形式的表现比另一种表现更好吗?除了在Oracle与SQL Server中定义表的方式之外,在Oracle或SQL Server中,一种形式的连接是否比另一种更好?如果您包含更多表格,例如3或4,该怎么办?这是否会改变性能特征,假设构造查询以返回等效的记录集?
答案 0 :(得分:0)
我的问题是:一种形式的表现比另一种表现更好吗?
他们不应该。您可以检查您的执行计划是否确定,但我使用的每个RDBMS都会生成与ANSI-92显式连接相同的逗号(ANSI-89)连接计划。 (注意,逗号连接并没有停止成为ANSI SQL,只是ANSI-92是显式语法首次出现的地方。)
除了如何在Oracle与SQL Server中定义表之外,在Oracle或SQL Server中,一种形式的连接是否比另一种更好?
就服务器而言,没有。
如果您包含更多表格,例如3或4,该怎么办?这是否会改变性能特征,假设构造查询以返回等效的记录集?
这是可能的。使用逗号连接,我不确定是否可以使用括号来控制JOIN顺序,就像使用显式连接一样:
SELECT *
FROM Table1 t1
INNER JOIN (
Table2 t2
INNER JOIN Table3 t3
t2.id = t3.id)
ON t1.id = t2.id
此可以影响整体查询效果(无论好坏)。我不确定如何使用逗号连接完成相同级别的控制,但我从未完全学习逗号连接语法。我不知道你是否可以说Table1 t1, (Table2 t2, Table3 t3)
,但我不相信你可以。我认为你必须使用子查询来做到这一点。
显式连接的主要优点是:
Table1 t1, Table2 t2, Table3 t3
,然后必须深入了解WHERE子句以确定其中一个连接是否为外连接。这也意味着WHERE子句没有填充所有这些连接条件,你知道在修改查询时你不关心更改。+
和*=
混淆以使您的外部联接正确。以上所有内容都使显式连接语法更易于维护,这对于软件来说是一个非常重要的因素。