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;
查看执行计划
然后使用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;
查看执行计划
通过对比查询计划,它们二者之间性能完全一样,虽然这样但是我还是建议你使用新语法
1)出于安全性的考虑,刚才我们提到过旧语法不能使用外连接,在查询中我们同时使用旧语法,新语法是个不明智的选择
2)便于维护
交叉连接应用
操作Product 表
添加索引:
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;
看执行计划
从查询计划我们可以看出,刚才在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;
查看执行计划
从执行计划我们可以看出,price列上的索引指被扫描了一次,通过一次扫描计算两个聚合函数.从而优化了查询效率.