如果某个语句包含对多个服务器的引用,或者使用远程服务器不支持的 SQL 功能,则会将查询分解为多个较简单的部分。
通过删除不能传递的部分并让 SQL Anywhere 执行工作,可以对 SELECT 语句进行分解。例如,假设远程服务器不能处理以下语句中的 ATAN2 函数:
SELECT a,b,c WHERE ATAN2( b, 10 ) > 3 AND c = 10; |
发送到远程服务器的语句将被转换为:
SELECT a,b,c WHERE c = 10; |
然后,SQL Anywhere 在本地将 [WHERE ATAN2( b, 10 ) > 3
] 应用到中间结果集。
当连接两个表时,将选择一个表作为外表。根据应用到外表的 WHERE 条件对外表进行扫描。对于找到的每个符合条件的行,将对另一个表(称为内部表)进行扫描以查找符合连接条件的行。
当引用远程表时将使用相同的算法。因为搜索远程表通常要比搜索本地表的开销高很多(由于网络 I/O),所以将采取一切办法让远程表成为连接中最外层的表。
找到符合条件的行时,如果 SQL Anywhere 不能将 UPDATE 或 DELETE 语句完整地传递给远程服务器,则它必须将该语句转换成一个表扫描,该表扫描包含原始 WHERE 子句的尽可能多的部分,后跟指定 WHERE CURRENT OF cursor-name 的定位 UPDATE 或 DELETE 语句。
例如,如果远程服务器不支持函数 ATAN2:
UPDATE t1 SET a = atan2( b, 10 ) WHERE b > 5; |
将被转换为以下内容:
SELECT a,b FROM t1 WHERE b > 5; |
每次找到一行时,SQL Anywhere 都会计算出 a 的新值并发出:
UPDATE t1 SET a = 'new value' WHERE CURRENT OF CURSOR; |
如果 a 已有等于该新值的值,则没有必要执行定位的 UPDATE,因此也不会远程发送定位的 UPDATE。
为了处理需要表扫描的 UPDATE 或 DELETE 语句,远程数据源必须支持执行定位 UPDATE 或 DELETE (WHERE CURRENT OF cursor-name) 的功能。某些数据源不支持此功能。
如果需要中间临时表,则不能执行 UPDATE 或 DELETE。这种情况发生在具有 ORDER BY 的查询和某些具有子查询的查询中。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |