第四十五章 SQL命令 FROM(一)

如题所述

第1个回答  2022-07-28
一个SELECT子句,指定要查询的一个或多个表。

FROM 子句指定在 SELECT 语句中查询数据的一个或多个表(或视图或子查询)。
如果没有查询表数据,则 FROM 子句是可选的,如下所述。

多个表被指定为逗号分隔的列表,或者由其他 JOIN 语法分隔的列表。
可以为每个表名提供一个别名。

在 SELECT 语句中为多个表指定字段名时使用表名别名。
如果 FROM 子句中指定了两个(或更多)表,可以通过指定 tablename 来指明需要哪个表的字段。
SELECT SELECT -item 子句中每个字段的字段名。
由于表名通常是长名称,因此短表名别名在此上下文中很有用( t-alias.fieldname )。

下面的示例展示了表名别名的使用:

AS关键字可以省略。
它是为了兼容性和清晰度而提供的。

table-ref 名称可以是限定的( schema.tablename )或非限定的( tablename )。
非限定表名(或视图名)的模式名使用模式搜索路径或系统范围的默认模式名提供:

当在 FROM 子句中指定多个表名时, SQL将对这些表执行连接操作。
执行的连接类型由每对表名之间的连接关键字短语或符号指定。
当两个表名用逗号分隔时,将执行交叉连接。

执行连接的顺序是由SQL查询优化器自动确定的,而不是基于查询中列出的表的顺序。
如果需要,可以通过指定查询优化选项来控制执行连接的顺序。

以下三个 SELECT 语句显示了两个单独表的行数,以及指定两个表的 SELECT 的行数。后者产生一个更大的表,即笛卡尔乘积,其中第一个表中的每一行都与第二个表中的每一行相匹配,这一操作称为交叉联接( Cross Join )。

从 Sample.Company、Sample.Vendor 中选择计数( * )

在大多数情况下,交叉连接的大量数据复制是不可取的,而某些其他类型的连接更可取。

如果在 SELECT 语句中指定 WHERE 子句,则执行交叉联接,然后 WHERE 子句谓词确定结果集。这等效于使用 ON 子句执行内联接。因此,以下两个示例返回相同的结果:

默认情况下, SQL查询优化器使用复杂而灵活的算法来优化涉及联接操作和/或多个索引的复杂查询的性能。在大多数情况下,这些默认值可提供最佳性能。但是,在极少数情况下,可能希望向查询优化器提供“提示”,指定查询优化的一个或多个方面。因此, SQL在 FROM 子句中提供了 OPTIMIZE-OPTION 关键字。可以按任意顺序指定多个优化关键字,并以空格分隔。

可以在简单的 SELECT 语句、 CREATE VIEW DEFINITION SELECT 语句或 FROM 子句的子查询 SELECT 语句中使用 OPTIMIZE-OPTION FROM 子句关键字。

此可选关键字指定提供任何好处的所有索引都用于查询联接顺序中的第一个表。只有在定义了多个索引时才应使用此关键字。优化器的默认设置是只使用优化器认为最有益的那些索引。默认情况下,这包括所有有效的相等索引和其他类型的选定索引。 %ALLINDEX 使用所有类型的所有可能有益的索引。测试所有索引的开销较大,但在某些情况下,它可能会提供比默认优化更好的性能。当使用多个范围条件索引和低效相等条件索引时,此选项特别有用。在这些情况下,查询优化器可能无法获得准确的索引选择性。 %ALLINDEX 可以与 %IGNOREINDEX 一起使用,以包括/排除特定索引。通常, %ALLINDEX 不应与 TOP 子句查询一起使用。

可以将 %STARTTABLE 与 %ALLINDEX 配合使用,以指定 %ALLINDEX 应用于哪个表。

可以使用 %NOINDEX 条件级别提示为特定条件的 %ALLINDEX 指定异常。
%NOINDEX 提示放置在不应该使用索引的每个查询选择条件的前面。
例如, WHERE %NOINDEX hiredate < ? 。
这在绝大多数数据没有被排除的情况下最常用。
对于小于( < )或大于( > )条件,使用%NOINDEX条件级别提示通常是有益的。
对于相等条件,使用 %NOINDEX 条件级提示没有任何好处。
对于连接条件, ON 子句连接支持 %NOINDEX 。

此可选关键字指定查询优化器应开始使用指定的表名执行联接。 tablename 为稍后在联接序列中指定的表命名。其余表的联接顺序留给查询优化器。此提示在功能上与 %STARTTABLE 相同,但为提供了以任意顺序指定联接表序列的灵活性。

tablename 必须是简单标识符,可以是表别名,也可以是非限定表名。不能使用限定表名( schema.table )。如果查询指定了表别名,则必须将该表别名用作表名。例如:

%FIRSTTABLE 和 %STARTTABLE 都允许指定用于联接操作的初始表。 %INORDER 允许指定用于联接操作的所有表的顺序。这三个关键词是相互排斥的;只指定一个和一个。如果不使用这些关键字,查询优化器将按照其认为最佳的顺序对表执行联接,而不管这些表的列出顺序如何。

不能使用 %FIRSTTABLE 或 %STARTTABLE 从左外部联接的右侧(或右外部联接的左侧)开始联接顺序。尝试这样做会导致 SQLCODE-34 错误:“优化器无法找到可用的联接顺序”。

此可选关键字指定编译器优化器检查所有可选联接序列以最大化访问性能。例如,在创建存储过程时,增加的编译时间可能值得提供更优化的访问。默认优化是,当 FROM 子句中有许多表时,不检查不太可能的连接序列。 %FULL 将覆盖此默认行为。

当 FROM 子句包含使用箭头语法访问的表时,可以同时指定 %INORDER 和 %FULL 关键字,这些表的顺序不受约束。

此可选关键字指定查询优化器忽略指定的索引或索引列表。(为了向后兼容,支持不推荐使用的同义词 %IGNOREINDICES 。)

在此关键字后面指定一个或多个索引名。多个索引名必须用逗号分隔。可以使用以下格式之一指定索引名:

方案名和表名是可选的。如果省略,则使用当前默认架构和指定为 from table-ref 的表名。星号( * )通配符指定指定表的所有索引名。可以按任意顺序指定索引名称。 SQL不会验证指定的索引名(或它们的模式名和表名);不存在或重复的索引名将被忽略。

通过使用此优化约束,可以使查询优化器不使用对特定查询不是最佳的索引。通过指定除一个索引名之外的所有索引名,实际上可以强制查询优化器使用剩余的索引。

还可以通过在条件前面加上 %noindex 关键字来忽略特定条件表达式的特定索引。

此可选关键字指定查询优化器按照表在 FROM 子句中列出的顺序执行联接。这最大限度地减少了编译时间。子查询的扁平化和索引使用不受影响。

%INORDER 不能与交叉联接或右外部联接一起使用。如果指定的表顺序与外部联接的要求不一致,则会生成 SQLCODE-34 错误:“Optimizer找不到可用的联接顺序。”为避免这种情况,建议在与外部联接一起使用 %INORDER 时,仅与ANSI样式的左外部联接或完全外部联接一起使用。

视图和表子查询按照它们在 FROM 子句中指定的顺序进行处理。

将此关键字与 %FIRSTTABLE 和 %STARTTABLE 进行比较,这两个关键字都只指定初始连接表,而不指定完整的连接顺序。

不能同时使用 %INORDER 和 %PARALLEL 优化;如果同时指定了这两个优化,则忽略 %PARALLEL 。

此可选关键字在量化的子查询(返回布尔值的子查询)的 FROM 子句中指定。它指定编译器优化器应抑制子查询展平。此优化选项禁用“扁平化”(默认),它通过将子查询有效地集成子查询到查询中来优化包含量化的子查询的查询:将子查询的表添加到查询的 FROM 子句中,并将子查询中的条件转换为查询的 WHERE 子句中的联接或限制。

以下是使用 %NOFLATTEN 的量化子查询的示例:

%INORDER 和 %STARTTABLE 优化隐式指定 %NOFLATTEN 。

此可选关键字在子查询的 FROM 子句中指定。它指定编译器优化器应该禁止子查询到视图的转换。此优化选项通过将子查询作为内联视图添加到查询的 FROM 子句来禁用对包含子查询的查询的优化;子查询与查询字段的比较将作为联接移动到查询的 WHERE 子句。

此可选关键字在流式子查询的 FROM 子句中指定-返回行的结果集的子查询,即封闭查询的 FROM 子句中的子查询。它指定编译器优化器应该禁止将子查询(或视图)合并到包含查询中。

在下面的示例中,查询优化器通常会通过对子查询执行 Sample.Person 的笛卡尔乘积联接来“减少”该查询。 %NOREDUCE 优化选项可防止出现这种情况。 IRIS改为在 GNAME 上构建临时索引,并在此临时索引上执行联接:

此可选关键字在量化的子查询(返回布尔值的子查询)的 FROM 子句中指定。它指定编译器优化器应禁止集值子查询优化( SVSO )。

在大多数情况下,集值子查询优化可以提高 [NOT] EXISTS 和 [NOT] In 子查询的性能,特别是对于只有一个可分离关联条件的子查询。
它通过用满足条件的数据值填充临时索引来实现这一点。
IRIS不是重复执行子查询,而是在临时索引中查找这些值。
例如, SVSO 优化了 NOT EXISTS (SELECT P.num FROM Products P WHERE S.num=P.num AND P.color='Pink') ,创建临时索引。

SVSO 优化了 ALL 或 ANY 关键字与相对操作符( > , >= , < ,或 <= )和子查询的子查询,如 … WHERE S.num > ALL (SELECT P.num…)
它通过将子查询表达式 sqbExpr (在本例中为 P.num )替换为 MIN(sqbExpr) 或 MAX(sqbExpr) 来实现这一点。
当 sqbExpr 上有索引时,它支持快速计算。

%INORDER 和 %STARTTABLE 优化不禁止集值子查询优化。

当使用带有 ORDER BY 子句的 TOP 子句时指定此可选关键字。
默认情况下, TOP 和 ORDER By 优化到第一行的最快时间。
相反,指定 %NOTOPOPT (没有 TOP 优化)将优化查询,以最快地检索完整的结果集。

此可选关键字在查询或子查询的 FROM 子句中指定。
它禁用为多个 OR 条件和针对 UNION 查询表达式的子查询提供的自动优化。
这些自动优化将多个 OR 条件转换为 UNION 子查询,或将 UNION 子查询转换为 OR 条件。
这些 UNION/OR 转换允许 EXISTS 和其他低级谓词迁移到顶级条件,以便IRIS查询优化器索引使用它们。
这些默认转换在大多数情况下都是可取的。

然而,在某些情况下,这些 UNION/OR 转换会带来很大的开销负担。
%NOUNIONOROPT 对与此 FROM 子句关联的 WHERE 子句中的所有条件禁用这些自动 UNION/OR 转换。
因此,在一个复杂的查询中,可以对一个子查询禁用这些自动UNION/OR优化,同时在其他子查询中允许它们。

UNION %PARALLEL 关键字禁用自动 UNION-to- or 优化。

%INORDER 和 %STARTTABLE 优化抑制了 OR-to-UNION 优化。
%INORDER 和 %STARTTABLE 优化不抑制 UNION-to-OR 优化。