计算序列在查询优化器内被作为序列项目,这个操作符有点类似于计算标量。不过它计算一个新值加到输出流。关键是它工作在一个排序Stream,包含被保留在行与行之间的状态。例如Ranking函数使用这个操作符。它通过使用一个不同的物理操作并强化了一些额外的限制(比如查询优化器能怎样记录这些表达式)。此操作符用在ranking和windows函数中。 ■Semi-Join
“semi-Join”(半连接)这个词来源于学术数据库词汇。它被用于描述一个操作:执行一个连接但是只返回来自于它输入值的一部分。查询处理器使用这个内部机制处理大多数的子查询。SQL Server以这种方式设置子查询,是因为这样可以使了解一整套可能为查询而作的转换更加容易。同时因为semi-join和常规的连接的运行时实现是类似的。与大多数的看法相反,一个子查询并不是总是执行并缓存在临时表中。它更多被看作一个常规的连接。查询优化器有转换规则,能转换常规的连接为半连接。
通常子查询是最自然的方式,代表你想使用 SQL的方式。有时候,子查询使用因为很少使用索引表,丢失声明,或写谓词的方式等而对查询优化器了解如何使用域限制属性框架而言是迟钝的而备受指责。但子查询是不可或缺的。因此,如果开发人员提倡“no subqueries”,请检查你的系统,其他的错误掩盖了表面现象。
我们用一个例子说明:
Create table customers(custID int identity,custName nvarchar(100));create table Orders(orderid int identity,custid int,orderdate date,amount money);truncate table customerstruncate table Ordersinsert into customers(custName) values('Conor sdfsd');insert into customers(custName) values('paul randal');insert into Orders(custid,orderdate,amount) values(1,'2010-04-01',49.23);insert into Orders(custid,orderdate,amount) values(2,'2010-04-12',65.00);insert into Orders(custid,orderdate,amount) values(3,'2010-04-13',123.44);
1、使用inner join
2、使用distinct 加inner join
3、使用子查询
可以看到,有时子查询反而比inner join有更低的成本评估。
注意:左、右Semi-Join必须处理操作中保留的子行。不幸的是,对于任何混淆这些操作的意思的人而言,SQL Server ManaggementStudio和前面的工具中设置的计划被转换了。在转换格式上left 代表top,right代表bottom。 ■Apply
"Cross Apply"和"Outer Apply"在SQL Server2005中新增,它们代表一种特殊的子查询(一个左输出的值通过一个参数连接到右child。)有时,这被叫做"correlated nested loops join",它代表通过一个参数到另外一个子查询。最常见的一个应用是一个索引lookup join。
Create table idx1(col1 int primary key,col2 int);create table idx2(col1 int primary key,col2 int);goselect * from idx1cross apply(select * from idx2 where idx1.col1=idx2.col1) as aselect * from idx1 cinner join idx2 o on c.col1=o.col1