1.旧语法和新语法

旧语法由ANSI SQL-89引入的,它与新语法的区别在与没有JOIN关键字和ON子句:SELECT T1.*,T2.* FROM T1,T2 WHERE

新语法由ANSI SQL-92引入的,它引入了JOIN关键字,ON子句 SELECT T1.*,T2.* FROM T1 JOIN T2 ON <子句> WHERE

旧语法ANSI SQL-89只支持内连接和交叉连接,不支持外连接

2.交叉连接(CROSS JOIN)

我现在使用cross join来查询Employee 表的信息

--cross join SELECT E1.Name,E1.Title AS emp1, E2.Name,E2.Title AS emp2 FROM Employee AS E1 CROSS JOIN Employee AS E2;

查看执行计划

T-SQL 表连接(内连接,外连接,交叉连接)

然后使用ANSI SQl-89旧语法来实现

--ANSI SQL-89语法 SELECT E1.Name,E1.Title AS emp1, E2.Name,E2.Title AS emp2 FROM Employee AS E1,Employee AS E2;

查看执行计划

T-SQL 表连接(内连接,外连接,交叉连接)

通过对比查询计划,它们二者之间性能完全一样,虽然这样但是我还是建议你使用新语法

1)出于安全性的考虑,刚才我们提到过旧语法不能使用外连接,在查询中我们同时使用旧语法,新语法是个不明智的选择

2)便于维护

交叉连接应用

操作Product 表

T-SQL 表连接(内连接,外连接,交叉连接)

添加索引:

CREATE INDEX id_price on dbo.Product(Price);

任务对于每个产品的价格占总价格,平均价格的百分比

下面使用子查询聚合查询

SELECT ProductName, Price, CAST(Price/(SELECT SUM(Price) FROM Product)* 100 AS NUMERIC(5,2)) AS Psp, CAST(Price/(SELECT AVG(Price) FROM Product)* 100 AS NUMERIC(5,2)) AS Asp FROM Product GROUP BY ProductName,Price;

执行计划

T-SQL 表连接(内连接,外连接,交叉连接)

从查询计划我们可以看出,刚才在price列上创建的索引被扫描了2次,一次用于SUM(),一次用于AVG(),如果没有包含聚合列的索引,需要为每个子查询扫描一次.

现在我们使用交叉连接来进行优化,我们可以在一个查询中计算所有的聚合,而且在查询中只需要对表,索引进行一次扫描

WITH Aggs AS ( SELECT SUM(Price) AS sumP,AVG(Price) AS avgP FROM Product ) SELECT ProductName, Price, CAST(Price / sumP * 100 AS NUMERIC(5,2)) AS Psp, CAST(Price / avgP * 100 AS NUMERIC(5,2)) AS AsP FROM Product CROSS JOIN Aggs;

查看执行计划

T-SQL 表连接(内连接,外连接,交叉连接)

执行计划我们可以看出,price列上的索引指被扫描了一次,通过一次扫描计算两个聚合函数.从而优化了查询效率.

相关文章: