查询优化程序会自动将许多使用子查询的查询改写为连接。执行这一转换不需要用户执行任何操作。本节介绍哪些子查询可以转换为连接,以便您可以了解数据库中查询的性能。
要使多层查询能够改写为连接的形式,必须满足一定条件,而对不同的运算符类型以及不同的查询和子查询结构,这些条件也会有差异。请回想一下,在查询的 WHERE 子句中出现子查询时的情况,其形式如下
SELECT select-list FROM table WHERE [NOT] expression comparison-operator ( subquery-expression ) | [NOT] expression comparison-operator { ANY | SOME } ( subquery-expression ) | [NOT] expression comparison-operator ALL ( subquery-expression ) | [NOT] expression IN ( subquery-expression ) | [NOT] EXISTS ( subquery-expression ) GROUP BY group-by-expression HAVING search-condition
例如,考虑以下请求:"Clarke 女士和 Suresh 女士何时下的订单,是通过哪些销售代表下的订单?"可以通过以下查询回答上述请求:
SELECT OrderDate, SalesRepresentative FROM SalesOrders WHERE CustomerID IN ( SELECT ID FROM Customers WHERE Surname = 'Clarke' OR GivenName = 'Suresh' ); |
OrderDate | SalesRepresentative |
---|---|
2001-01-05 | 1596 |
2000-01-27 | 667 |
2000-11-11 | 467 |
2001-02-04 | 195 |
... | ... |
该子查询生成与其姓名在 WHERE 子句中列出的两个客户相对应的客户 ID 的列表,并且主查询查找与这两位女士的订单相对应的订单日期和销售代表。
可以使用连接来回答同样的问题。下面是该查询的替代形式,使用了两表连接:
SELECT OrderDate, SalesRepresentative FROM SalesOrders, Customers WHERE CustomerID=Customers.ID AND ( Surname = 'Clarke' OR GivenName = 'Suresh' ); |
此查询形式将 SalesOrders 表连接到 Customers 表,以查找每个客户的订单,然后只返回 Suresh 和 Clarke 的记录。
在某些情况下,子查询有效,但连接无效。例如:
SELECT Name, Description, Quantity FROM Products WHERE Quantity < 2 * ( SELECT AVG( Quantity ) FROM SalesOrderItems ); |
name | Description | Quantity |
---|---|---|
Tee Shirt | Tank Top | 28 |
Baseball Cap | Wool cap | 12 |
Visor | Cloth Visor | 36 |
... | ... | ... |
在此例中,内部查询是汇总查询,而外部查询不是汇总查询,因此,无法通过一个简单连接来合并这两个查询。
跟在比较运算符之后的子查询
跟在 ANY、ALL 或 SOME 之后的子查询
跟在 IN 之后的子查询
跟在 EXISTS 之后的子查询
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |