Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询处理 » 查询优化与执行 » 优化程序的工作原理

 

在查询中使用谓语

谓语是用逻辑运算符 AND 和 OR 连接在一起的条件表达式,可在 WHERE、HAVING 或 ON 子句中组成条件集合。在 SQL 中,求值结果为 UNKNOWN 的谓语将解释为 FALSE。

可以利用索引从表中检索行的谓语被称作可优化搜索谓语。此名称来自于短语 search argument-able。涉及将列与常量、其它列或表达式进行比较的谓语可能是可优化搜索谓语。

以下语句中的谓语是可优化搜索谓语。SQL Anywhere 可以使用 Employees 表的主索引有效地计算该谓语的值。

SELECT *
FROM Employees
WHERE Employees.EmployeeID = 102;

在计划中,这会显示为: Employees<Employees>

对比之下,以下谓语就不是可优化搜索谓语。虽然 EmployeeID 列被编入主索引,但由于结果中包含所有行(或除一行之外的所有行),因此使用此索引并不会加快计算速度。

SELECT *
FROM Employees
where Employees.EmployeeID <> 102;

在计划中,这会显示为: Employees<seq>

类似地,没有任何索引可以帮助搜索名字以字母 k 结尾的所有雇员。同样,计算此结果的唯一方法是分别检查每一行。

函数

通常,在列名上包含函数的谓语不是可优化搜索谓语。例如,在以下查询上将不使用索引:

SELECT * 
FROM SalesOrders
WHERE YEAR ( OrderDate ) ='2000';

要避免使用函数,可重写查询以使其成为可优化搜索查询。例如,可以改写上述查询:

SELECT * 
FROM SalesOrders
WHERE OrderDate > '1999-12-31'
AND OrderDate < '2001-01-01';

如果将函数值存储在计算列中并在该列上建立索引,则使用函数的查询就会成为可优化搜索查询。计算列是从表上其它列中获得值的列。例如,如果有一个名为 OrderDate 的列,它保存订单的日期,则可以创建一个名为 OrderYear 的计算列,该列保存从 OrderDate 列中抽取的年份值。

ALTER TABLE SalesOrders
ADD OrderYear INTEGER
COMPUTE ( YEAR( OrderDate ) );

然后,可以按普通方式添加列 OrderYear 的索引:

CREATE INDEX IDX_year
ON SalesOrders ( OrderYear );

如果随即执行以下语句,则数据库服务器会发现存在一个包含此信息的索引列,并使用该索引来回应查询。

SELECT * FROM SalesOrders
WHERE YEAR( OrderDate ) = '2000';

为了进行列替代,计算列的域必须与 COMPUTE 表达式的域相同。在上面的示例中,如果 YEAR( OrderDate ) 返回的是字符串而不是整数,优化程序就不会替代表达式的计算列,并且索引 IDX_year 也不能用于检索所需的行。

有关计算列的详细信息,请参见使用计算列

示例

在下面的每个示例中,属性 xy 分别是一个表中的两个列。属性 z 包含在一个单独的表中。假定这些属性中的每一个都有索引。

可优化搜索 非可优化搜索
x = 10 x < > 10
x IS NULL x IS NOT NULL
x > 25 x = 4 OR y = 5
x = z x = y
x IN (4, 5, 6) x NOT IN (4, 5, 6)
x LIKE 'pat%' x LIKE '%tern'
x = 20 - 2 x + 2 = 20

有时,谓语是否是可优化搜索谓语可能不是很明显。在这些情况下,您可能能够重写该谓语,使其成为可优化搜索谓语。对于每一个示例,都可以基于字母表中 u 紧接在 t 后这一事实来重写谓语 x LIKE 'pat%':x >= 'pat' and x < 'pau'。采用这种形式时,属性 x 上的索引对于查找有限范围内的值非常有用。幸运的是,SQL Anywhere 会自动进行此特定转换。

用于在表上进行索引检索的可优化搜索谓语属于匹配谓语。WHERE 子句可以包含多个匹配谓语。最合适的谓语取决于连接策略。在考虑替代连接策略时,优化程序会重新计算它对匹配谓语做出的选择。请参见通过谓语推导发现可利用的条件