谓语是用逻辑运算符 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 也不能用于检索所需的行。
有关计算列的详细信息,请参见使用计算列。
在下面的每个示例中,属性 x 和 y 分别是一个表中的两个列。属性 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 子句可以包含多个匹配谓语。最合适的谓语取决于连接策略。在考虑替代连接策略时,优化程序会重新计算它对匹配谓语做出的选择。请参见通过谓语推导发现可利用的条件。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |