Oracle官方文档翻译《Database Concepts 26ai》第10章-SQL

10 SQL(10 SQL)

本章概述了结构化查询语言 (SQL) 以及 Oracle AI 数据库如何处理 SQL 语句。

  • SQL 简介

    SQL(读作"sequel")是一种基于集合的高级声明式计算机语言,所有程序及用户均通过它来访问 Oracle 数据库中的数据。

  • SQL 语句概述

    在 Oracle 数据库中对信息执行的所有操作都通过运行 SQL 语句来完成。一条 SQL 语句是由标识符、参数、变量、名称、数据类型和 SQL 保留字组成的计算机程序或指令。

  • 优化器概述

    要理解 Oracle AI 数据库如何处理 SQL 语句,就必须理解数据库中名为优化器的部分(也称查询优化器或基于成本的优化器)。所有 SQL 语句都使用优化器来确定访问指定数据的最有效方式。

  • SQL 处理概述

    本节解释 Oracle AI 数据库如何处理 SQL 语句。具体而言,本节说明了数据库创建对象时的 DDL 处理、修改数据时的 DML 处理以及检索数据的查询处理方式。


Introduction to SQL(SQL 简介)

SQL(读作"sequel")是一种基于集合的高级声明式计算机语言,所有程序及用户均通过它来访问 Oracle 数据库中的数据。

尽管某些 Oracle 工具和应用程序会掩盖 SQL 的使用,但所有数据库任务都是通过 SQL 执行的。任何其他数据访问方法都会绕过 Oracle AI 数据库内置的安全性,并可能危及数据安全和完整性。

SQL 为 Oracle AI 数据库这类关系数据库提供了接口。SQL 将以下任务统一在一套一致的语言中:

  • 创建、替换、更改和删除对象
  • 插入、更新和删除表行
  • 查询数据
  • 控制数据库及其对象的访问
  • 保证数据库的一致性和完整性

SQL 可以交互式使用,即手动将语句输入程序。SQL 语句也可嵌入用 C 或 Java 等其他语言编写的程序中。

  • SQL 数据访问

    计算机语言有两大类:声明式语言是非过程化的,描述应该做什么 ;而过程化语言(如 C++ 和 Java)则描述应该如何做

  • SQL 标准

    Oracle 努力遵循行业公认标准,并积极参与 SQL 标准委员会。

另请参见

  • 服务器端编程简介
  • 《Oracle AI 数据库开发指南》以了解如何选择编程环境
  • 《Oracle AI 数据库 SQL 语言参考》以了解 SQL 简介

SQL Data Access(SQL 数据访问)

计算机语言有两大类:声明式语言是非过程化的,描述应该做什么 ;而过程化语言(如 C++ 和 Java)则描述应该如何做

SQL 是声明式的,因为用户指定的是他们想要的结果,而不是如何得到结果。例如,以下语句查询姓氏以 K 开头的员工记录:

sql 复制代码
SELECT   last_name, first_name
FROM     hr.employees
WHERE    last_name LIKE 'K%'
ORDER BY last_name, first_name;

数据库负责生成导航数据并检索所请求结果的过程。SQL 的声明式特性使您能在逻辑层面处理数据。您只需在操作数据时才需关注实现细节。

数据库在单个步骤中检索所有满足 WHERE 条件(也称谓词)的行。数据库可将这些行作为一个单元传递给用户、另一条 SQL 语句或应用程序。应用程序无需逐行处理这些行,开发者也无需知道这些行在物理上是如何存储或检索的。

所有 SQL 语句都使用优化器------数据库的一个组件,用于确定访问请求数据的最有效方式。Oracle 数据库还支持一些技术,您可利用这些技术让优化器更好地完成其工作。

另请参见

《Oracle AI 数据库 SQL 语言参考》以获取有关 SQL 语句及 SQL 其他部分(如运算符、函数和格式模型)的详细信息


SQL Standards(SQL 标准)

Oracle 努力遵循行业公认标准,并积极参与 SQL 标准委员会。

行业公认委员会包括美国国家标准学会(ANSI)和国际标准化组织(ISO)。ANSI 和 ISO/IEC 均已接受 SQL 作为关系数据库的标准语言。

SQL 标准由十个部分组成。其中一个部分(SQL/RPR:2012)于 2012 年新增。另有五个部分在 2011 年进行了修订。其余四个部分仍采用 2008 年的版本。

Oracle SQL 包含许多对 ANSI/ISO 标准 SQL 语言的扩展,而 Oracle AI 数据库工具和应用程序则提供了更多额外的语句。借助 SQL*Plus、SQL Developer 和 Oracle Enterprise Manager 等工具,您可以针对 Oracle 数据库运行任何 ANSI/ISO 标准 SQL 语句,以及这些工具可用的任何附加语句或函数。

另请参见

  • 《Oracle AI 数据库:开始使用 Oracle AI 数据库开发》
  • 《Oracle AI 数据库 SQL 语言参考》了解 Oracle SQL 与标准 SQL 之间差异的说明
  • 《SQLPlus 用户指南与参考》了解 SQLPlus 命令,包括它们与 SQL 语句的区别

Overview of SQL Statements(SQL 语句概述)

在 Oracle 数据库中对信息执行的所有操作都通过运行 SQL 语句来完成。一条 SQL 语句是由标识符、参数、变量、名称、数据类型和 SQL 保留字组成的计算机程序或指令。

注意 :SQL 保留字在 SQL 中具有特殊含义,不得用于任何其他目的。例如,SELECTUPDATE 是保留字,不应被用作表名。

一条 SQL 语句必须相当于一条完整的 SQL 句子,例如:

sql 复制代码
SELECT last_name, department_id FROM employees

Oracle AI 数据库只运行完整的 SQL 语句。像下面这样的片段会产生错误,提示需要更多文本:

sql 复制代码
SELECT last_name;

Oracle SQL 语句分为以下类别:

  • 数据定义语言(DDL)语句
  • 数据操纵语言(DML)语句
  • 事务控制语句
  • 会话控制语句
  • 系统控制语句
  • 嵌入式 SQL 语句

Data Definition Language (DDL) Statements(数据定义语言(DDL)语句)

数据定义语言(DDL)语句用于定义、结构性更改和删除模式对象。

DDL 允许您更改对象的属性,而无需更改访问该对象的应用程序。例如,您可以为人力资源应用程序访问的表添加一列,而无需重写该应用程序。您还可以在数据库用户正处于工作状态时,使用 DDL 更改对象的结构。

更具体地说,DDL 语句使您能够:

  • 创建、更改和删除模式对象及其他数据库结构,包括数据库本身和数据库用户。大多数 DDL 语句以关键字 CREATEALTERDROP 开头。
  • 删除模式对象中的所有数据,但不删除这些对象的结构(TRUNCATE)。

注意 :与 DELETE 不同,TRUNCATE 不生成撤销数据,因此其速度比 DELETE 更快。同时,TRUNCATE 不会触发删除触发器。

  • 授予和撤销权限及角色(GRANTREVOKE)。
  • 打开和关闭审计选项(AUDITNOAUDIT)。
  • 向数据字典添加注释(COMMENT)。

示例 10-1:DDL 语句

以下示例使用 DDL 语句创建 plants 表,然后使用 DML 向表中插入两行。接着使用 DDL 更改表结构,向用户授予和撤销对该表的读取权限,最后删除该表。

sql 复制代码
CREATE TABLE plants
    ( plant_id    NUMBER PRIMARY KEY, 
      common_name VARCHAR2(15) );
INSERT INTO plants VALUES (1, 'African Violet'); -- DML语句
INSERT INTO plants VALUES (2, 'Amaryllis');      -- DML语句
ALTER TABLE plants ADD 
    ( latin_name VARCHAR2(40) );
GRANT READ ON plants TO scott;
REVOKE READ ON plants FROM scott;
DROP TABLE plants;

在数据库执行 DDL 语句之前,会隐式提交;随后,会立即执行 COMMITROLLBACK。在上面的示例中,两条 INSERT 语句后跟着一条 ALTER TABLE 语句,因此数据库提交了这两条 INSERT 语句。如果 ALTER TABLE 语句成功,则数据库提交此语句;否则,数据库回滚此语句。无论哪种情况,那两条 INSERT 语句都已被提交。

另请参见

  • 《Oracle AI 数据库安全指南》了解权限和角色
  • 《Oracle AI 数据库:开始使用 Oracle AI 数据库开发》和《Oracle AI 数据库管理员指南》了解如何创建模式对象
  • 《Oracle AI 数据库开发指南》了解阻塞与非阻塞 DDL 的区别
  • 《Oracle AI 数据库 SQL 语言参考》获取 DDL 语句列表

Data Manipulation Language (DML) Statements(数据操纵语言(DML)语句)

数据操纵语言(DML)语句用于查询或操作现有模式对象中的数据。

DDL 语句改变数据库的结构,而 DML 语句则查询或更改数据库的内容。例如,ALTER TABLE 改变表的结构,而 INSERT 则向表中添加一行或多行。

DML 语句是使用最频繁的 SQL 语句,使您能够:

  • 从一个或多个表或视图中检索或获取数据(SELECT)。
  • 通过指定列值列表或使用子查询来选择并操作现有数据,将新数据行添加到表或视图中(INSERT)。
  • 更改表或视图中现有行的列值(UPDATE)。
  • 按条件将行更新或插入到表或视图中(MERGE)。
  • 从表或视图中删除行(DELETE)。
  • 查看 SQL 语句的执行计划(EXPLAIN PLAN)。
  • 锁定表或视图,临时限制其他用户的访问(LOCK TABLE)。

以下示例使用 DML 查询 employees 表,然后使用 DML 向 employees 中插入一行,更新该行,最后将其删除:

sql 复制代码
SELECT * FROM employees;
INSERT INTO employees (employee_id, last_name, email, job_id, hire_date, 
salary)
  VALUES (1234, 'Mascis', 'JMASCIS', 'IT_PROG', '14-FEB-2008', 9000);
UPDATE employees SET salary=9100 WHERE employee_id=1234;
DELETE FROM employees WHERE employee_id=1234;

构成一个逻辑工作单元的一组 DML 语句称为事务。例如,一个转账事务可能包括三个独立操作:减少储蓄账户余额、增加支票账户余额,以及在交易历史表中记录转账。与 DDL 语句不同,DML 语句不会隐式提交当前事务。

  • SELECT 语句

    查询是从表或视图中检索数据的操作。

  • 连接

    连接是将两个或多个表、视图或物化视图中的行组合在一起的查询。

  • 子查询

    子查询是嵌套在另一条 SQL 语句中的 SELECT 语句。当要解决同一个问题却必须执行多个查询时,子查询很有用。

另请参见

  • [DML 与 DDL 处理的差异](#DML 与 DDL 处理的差异)
  • 事务简介
  • 《Oracle AI 数据库:开始使用 Oracle AI 数据库开发》了解如何查询和操作数据
  • 《Oracle AI 数据库 SQL 语言参考》获取 DML 语句列表

SELECT Statements(SELECT 语句)

查询是从表或视图中检索数据的操作。

SELECT 是唯一可用于查询数据的 SQL 语句。执行 SELECT 语句所检索到的数据集称为结果集。

下表展示了 SELECT 语句中常见的一个必需关键字和三个可选关键字,并将 SELECT 语句的功能与这些关键字关联起来。

表 10-1:SQL 语句中的关键字

关键字 是否必需? 描述 能力
SELECT 指定应在结果中显示哪些列。表达式是由一个或多个值、运算符和 SQL 函数组合而成,可计算出一个值。出现在 SELECT 关键字之后、FROM 子句之前的表达式列表称为选择列表。 投影
FROM 指定应从哪些表或视图中检索数据。 连接
WHERE 指定一个条件来过滤行,生成表的行子集。一个条件由一个或多个表达式和逻辑(布尔)运算符组合而成,并返回 TRUEFALSEUNKNOWN 值。 选择
ORDER BY 指定行的显示顺序。

另请参见

《Oracle AI 数据库 SQL 语言参考》了解 SELECT 语法和语义


Joins(连接)

连接是将两个或多个表、视图或物化视图中的行组合在一起的查询。

以下示例连接了 employeesdepartments 表(FROM 子句),只选择满足指定条件的行(WHERE 子句),并使用投影从两列中检索数据(SELECT)。示例输出紧随 SQL 语句之后。

sql 复制代码
SELECT email, department_name
FROM   employees 
JOIN   departments
ON     employees.department_id = departments.department_id
WHERE  employee_id IN (100,103)
ORDER BY email;

EMAIL                     DEPARTMENT_NAME
------------------------- ------------------------------
AHUNOLD                   IT
SKING                     Executive

下图展示了前述查询连接中的投影和选择操作。

Figure 10-1 Projection and Selection(图10-1 投影与选择)

大多数连接至少有一个连接条件,该条件要么在 FROM 子句中,要么在 WHERE 子句中,用于比较两个表中的两列,每列来自不同的表。数据库将成对的行组合起来(每对行各包含来自一个表的一行),对于这些行而言,连接条件的结果为 TRUE。优化器根据连接条件、索引以及表的任何可用统计信息来确定数据库连接表的顺序。

连接类型包括:

  • 内连接

    内连接是两个或多个表的连接,只返回满足连接条件的行。例如,如果连接条件是 employees.department_id=departments.department_id,则不满足此条件的行将不被返回。

  • 外连接

    外连接返回所有满足连接条件的行,同时还会从一个表中返回那些在另一个表中找不到匹配行的行。

    • 表 A 和表 B 的左外连接结果始终包含左表 A 的所有记录,即使连接条件没有匹配右表 B 中的记录也是如此。如果 B 中没有匹配的行,则对于在 B 中无匹配的行,B 的列包含空值。例如,如果不是所有员工都有部门,那么对 employees(左表)和 departments(右表)进行左外连接会检索 employees 中的所有行,即使 departments 中没有满足连接条件(employees.department_id 为空)的行也是如此。

    • 表 A 和表 B 的右外连接结果包含右表 B 的所有记录,即使连接条件没有匹配左表 A 中的行也是如此。如果 A 中没有匹配的行,则对于在 A 中无匹配的行,A 的列包含空值。例如,如果不是所有部门都有员工,那么对 employees(左表)和 departments(右表)进行右外连接会检索 departments 中的所有行,即使 employees 中没有满足连接条件的行也是如此。

    • 全外连接是左外连接和右外连接的组合。

  • 笛卡尔积

    如果连接查询中的两个表没有连接条件,则数据库会执行笛卡尔连接。一个表中的每一行都会与另一个表中的每一行进行组合。例如,如果 employees 有 107 行,departments 有 27 行,那么笛卡尔积将包含 107*27 行。笛卡尔积很少有用。

另请参见

  • 《Oracle AI 数据库 SQL 调优指南》了解连接
  • 《Oracle AI 数据库 SQL 语言参考》了解连接的详细描述和示例

Subqueries(子查询)

子查询是嵌套在另一条 SQL 语句中的 SELECT 语句。当要解决同一个问题却必须执行多个查询时,子查询很有用。

语句中的每个查询部分称为一个查询块。在以下查询中,括号内的子查询就是内层查询块:

sql 复制代码
SELECT first_name, last_name 
FROM   employees
WHERE  department_id 
IN     ( SELECT department_id 
         FROM departments 
         WHERE location_id = 1800 );

内层的 SELECT 语句检索位置 ID 为 1800 的部门的 ID。外层查询块需要这些部门 ID,它用于检索子查询提供的那些部门中员工的姓名。

SQL 语句的结构并不强制数据库先执行内层查询。例如,数据库可以将整个查询重写成 employeesdepartments 的一个连接,这样,子查询就绝不会单独执行。又如,虚拟专用数据库(VPD)功能可以使用 WHERE 子句来限制对 employees 的查询,这样数据库就会先查询 employees,然后再获取部门 ID。优化器会确定最佳的步骤序列来检索所请求的行。

另请参见

《Oracle AI 数据库安全指南》详细了解 VPD


Transaction Control Statements(事务控制语句)

事务控制语句管理由 DML 语句所做的更改,并将 DML 语句分组到事务中。

这些语句使您能够:

  • 使对事务的更改永久生效(COMMIT)。
  • 撤销事务中的更改,可从自事务开始以来撤销(ROLLBACK),也可从保存点以来撤销(ROLLBACK TO SAVEPOINT)。保存点是用户在事务上下文中声明的中间标记。

注意ROLLBACK 语句结束事务,但 ROLLBACK TO SAVEPOINT 不会。

  • 设置一个可回滚到的点(SAVEPOINT)。
  • 为事务建立属性(SET TRANSACTION)。
  • 指定是在每条 DML 语句之后,还是在事务提交时才检查可延迟完整性约束(SET CONSTRAINT)。

以下示例启动一个名为 "Update salaries" 的事务。该示例创建了一个保存点,更新了员工工资,然后将事务回滚至该保存点。示例随即把工资更新为另一个值并提交。

sql 复制代码
SET TRANSACTION NAME 'Update salaries';
SAVEPOINT before_salary_update;
UPDATE employees SET salary=9100 WHERE employee_id=1234; -- DML
ROLLBACK TO SAVEPOINT before_salary_update;
UPDATE employees SET salary=9200 WHERE employee_id=1234; -- DML
COMMIT COMMENT 'Updated salaries';

另请参见


Session Control Statements(会话控制语句)

会话控制语句动态管理用户会话的属性。

会话是数据库实例内存中的一个逻辑实体,代表当前用户登录数据库的状态。一个会话从用户通过数据库验证时起,一直持续到用户断开连接或退出数据库应用程序为止。

会话控制语句使您能够:

  • 通过执行专门的功能来更改当前会话,例如设置默认日期格式(ALTER SESSION)。
  • 为当前会话启用和禁用角色(SET ROLE),角色是权限的集合。

以下语句动态地将您会话的默认日期格式更改为 'YYYY MM DD-HH24:MI:SS'

sql 复制代码
ALTER SESSION 
   SET NLS_DATE_FORMAT = 'YYYY MM DD HH24:MI:SS';

会话控制语句不会隐式提交当前事务。

另请参见

  • 连接与会话
  • 《Oracle AI 数据库 SQL 语言参考》了解 ALTER SESSION 的语法和语义

System Control Statement(系统控制语句)

系统控制语句用于更改数据库实例的属性。

唯一的系统控制语句是 ALTER SYSTEM。它使您能够更改设置,如共享服务器的最小数量、终止会话,以及执行其他系统级任务。

系统控制语句的示例包括:

sql 复制代码
ALTER SYSTEM SWITCH LOGFILE; 
ALTER SYSTEM KILL SESSION '39, 23';

ALTER SYSTEM 语句不会隐式提交当前事务。

另请参见

《Oracle AI 数据库 SQL 语言参考》了解 ALTER SYSTEM 的语法和语义


Embedded SQL Statements(嵌入式 SQL 语句)

嵌入式 SQL 语句将 DDL、DML 和事务控制语句合并到过程化语言程序中。

嵌入式语句与 Oracle 预编译器一起使用。嵌入 SQL 是将 SQL 合并到过程化语言应用程序中的一种方法。另一种方法是使用过程化 API,如开放式数据库连接(ODBC)或 Java 数据库连接(JDBC)。

嵌入式 SQL 语句使您能够:

  • 定义、分配和释放游标(DECLARE CURSOROPENCLOSE)。
  • 指定数据库并连接到它(DECLARE DATABASECONNECT)。
  • 分配变量名称(DECLARE STATEMENT)。
  • 初始化描述符(DESCRIBE)。
  • 指定如何处理错误和警告条件(WHENEVER)。
  • 解析和运行 SQL 语句(PREPAREEXECUTEEXECUTE IMMEDIATE)。
  • 从数据库中检索数据(FETCH)。

另请参见


Overview of the Optimizer(优化器概述)

要理解 Oracle AI 数据库如何处理 SQL 语句,就必须理解数据库中名为优化器的部分(也称查询优化器或基于成本的优化器)。所有 SQL 语句都使用优化器来确定访问指定数据的最有效方式。

  • 优化器的使用

    优化器生成描述可能执行方法的执行计划。

  • 优化器组件

    优化器包含三个主要组件:转换器、估算器和计划生成器。

  • 访问路径

    访问路径是查询用于检索行的技术。

  • 优化器统计信息

    优化器统计信息是一组描述数据库及其中对象详细情况的数据。这些统计信息为数据存储和分布提供了一个统计上准确的图像,供优化器在评估访问路径时使用。

  • 优化器提示

    提示是 SQL 语句中的一段注释,用作给优化器的指令。


Use of the Optimizer(优化器的使用)

优化器生成描述可能执行方法的执行计划。

优化器通过综合考虑多个信息源来确定哪个执行计划最有效。例如,优化器会考虑查询条件、可用的访问路径、为系统收集的统计信息以及提示。

要执行一条 DML 语句,Oracle AI 数据库可能必须执行许多步骤。每个步骤要么从数据库中物理地检索数据行,要么为发出语句的用户准备这些行。数据库执行一条语句所采用的步骤会极大地影响该语句的运行速度。通常,处理一条 DML 语句有许多不同的方式。例如,访问表或索引的顺序可能会有所不同。

当确定一条 SQL 语句的最佳执行计划时,优化器会执行以下操作:

  • 评估表达式和条件
  • 检查完整性约束以了解更多数据信息,并基于这些元数据进行优化
  • 语句转换
  • 选择优化器目标
  • 选择访问路径
  • 选择连接顺序

优化器会为一条查询生成大多数可能的处理方式,并为生成的执行计划中的每个步骤分配一个成本。成本最低的执行计划会被选为要执行的查询计划。

注意:您可以在不执行某个执行计划的情况下,为 SQL 语句获取执行计划。唯有数据库实际用于执行查询的执行计划,才能准确地称为查询计划。

您可以通过设置优化器目标并为优化器收集代表性的统计信息来影响优化器的选择。例如,您可以将优化器目标设置为以下二者之一:

  • 总吞吐量
    ALL_ROWS 提示指示优化器尽可能快地将结果集的最后一行返回给客户端应用程序。

  • 初始响应时间
    FIRST_ROWS 提示指示优化器尽可能快地将第一行返回给客户端。

典型的交互式终端用户应用程序会受益于初始响应时间优化,而批处理、非交互式应用程序则会受益于总吞吐量优化。

另请参见

  • 《Oracle AI 数据库 PL/SQL 包和类型参考》了解如何使用 DBMS_STATS
  • 《Oracle AI 数据库 SQL 调优指南》了解更多关于优化器和使用提示的信息

Optimizer Components(优化器组件)

优化器包含三个主要组件:转换器、估算器和计划生成器。

下图描述了这些组件:

Figure 10-2 Optimizer Components(图10-2 优化器组件)

优化器的输入是一个解析后的查询。优化器执行以下操作:

  1. 优化器接收解析后的查询,并根据可用的访问路径和提示为 SQL 语句生成一组可能的计划。
  2. 优化器基于数据字典中的统计信息估算每个计划的成本。成本是一个估算值,与使用特定计划执行语句所需的预期资源使用量成正比。
  3. 优化器比较计划的成本,并选择成本最低的计划(称为查询计划),传递给行源生成器。
  • 查询转换器

    查询转换器确定改变查询的形式是否有助于优化器生成更好的执行计划。查询转换器的输入是一个解析后的查询,优化器将其表示为一组查询块。

  • 估算器

    估算器确定一个给定执行计划的总体成本。

  • 计划生成器

    计划生成器为提交的查询尝试不同的执行计划。优化器选择成本最低的计划。

另请参见

  • [SQL 解析](#SQL 解析)
  • [SQL 行源生成](#SQL 行源生成)

Query Transformer(查询转换器)

查询转换器确定改变查询的形式是否有助于优化器生成更好的执行计划。查询转换器的输入是一个解析后的查询,优化器将其表示为一组查询块。

另请参见

查询重写


Estimator(估算器)

估算器确定一个给定执行计划的总体成本。

估算器为实现此目标会生成三种不同类型的度量:

  • 选择率

    该度量表示来自某个行集的行所占的比例。选择率与查询谓词(如 last_name='Smith')或谓词的组合相关。

  • 基数

    该度量表示某个行集中的行数。

  • 成本

    该度量表示工作单元或资源使用量。查询优化器将磁盘 I/O、CPU 使用情况和内存使用情况作为工作单元。

如果有可用的统计信息,估算器会使用这些信息来计算这些度量。统计信息可以提高这些度量的准确性。


Plan Generator(计划生成器)

计划生成器为提交的查询尝试不同的执行计划。优化器选择成本最低的计划。

对于每个嵌套子查询和未合并的视图,优化器都会生成一个子计划。优化器将每个子计划表示为一个单独的查询块。计划生成器通过尝试不同的访问路径、连接方法和连接顺序来探索查询块的各种计划。

自适应查询优化功能会根据语句执行期间收集到的统计信息来更改执行计划。所有自适应机制都可以为语句执行最终计划,该计划可能与默认计划不同。自适应优化使用动态计划(在语句执行期间在子计划之间选择)或重新优化(在当前执行之后的执行中更改计划)。

另请参见

  • 《Oracle AI 数据库:开始使用性能调优》 了解 SQL 调优简介
  • 《Oracle AI 数据库 SQL 调优指南》 了解优化器组件和自适应优化

Access Paths(访问路径)

访问路径是查询用于检索行的技术。

例如,使用索引的查询与不使用索引的查询具有不同的访问路径。通常,索引访问路径最适用于检索一小部分表行的语句。而全扫描在访问表的很大一部分数据时更为高效。

数据库可以使用多种不同的访问路径从表中检索数据。以下是具有代表性的列表:

  • 全表扫描

    此类扫描读取表中的所有行,并过滤掉不满足选择条件的行。数据库会按顺序扫描段中的所有数据块,包括高水位线(HWM)之下的那些数据块,高水位线用于分隔已用空间和未用空间(参见"段空间和高水位线")。

  • Rowid 扫描

    行的 rowid 指定了包含该行的数据文件、数据块以及该行在块中的位置。数据库首先从语句的 WHERE 子句或通过索引扫描获取所选行的 rowid,然后根据 rowid 定位每个所选行。

  • 索引扫描

    此类扫描为 SQL 语句所访问的索引列值搜索索引(参见"索引扫描")。如果语句只访问索引中的列,则 Oracle AI 数据库会直接从索引中读取这些索引列值。

  • 簇扫描

    簇扫描从存储在索引表簇中的表检索数据,在索引表簇中,所有具有相同簇键值的行都存储在同一个数据块中(参见"索引簇概述")。数据库首先通过扫描簇索引来获取所选行的 rowid。然后 Oracle AI 数据库根据此 rowid 定位这些行。

  • 哈希扫描

    哈希扫描在哈希簇中定位行,在哈希簇中,所有具有相同哈希值的行都存储在同一个数据块中(参见"哈希簇概述")。数据库首先通过对语句指定的簇键值应用哈希函数来获取哈希值。然后 Oracle AI 数据库扫描包含具有此哈希值的行的数据块。

优化器根据语句可用的访问路径以及使用每种访问路径或路径组合的估算成本来选择访问路径。

另请参见

《Oracle AI 数据库:开始使用性能调优》和《Oracle AI 数据库 SQL 调优指南》了解访问路径


Optimizer Statistics(优化器统计信息)

优化器统计信息是一组描述数据库及其中对象详细情况的数据。这些统计信息为数据存储和分布提供了一个统计上准确的图像,供优化器在评估访问路径时使用。

优化器统计信息包括:

  • 表统计信息

    包括行数、块数和平均行长度。

  • 列统计信息

    包括列中不同值的数量、空值的数量以及数据的分布情况。

  • 索引统计信息

    包括叶块数和索引层级数。

  • 系统统计信息

    包括 CPU 和 I/O 的性能与利用率。

Oracle AI 数据库会自动收集所有数据库对象的优化器统计信息,并作为一项自动化维护任务来保持这些统计信息。您也可以使用 DBMS_STATS 包手动收集统计信息。该 PL/SQL 包可以修改、查看、导出、导入和删除统计信息。

注意:优化器统计信息是为了查询优化而创建的,并存储在数据字典中。请勿将这些统计信息与通过动态性能视图可见的性能统计信息混淆。

优化器统计信息顾问是一款内置的诊断软件,用于分析您当前收集统计信息的方式、现有统计信息收集作业的有效性,以及已收集统计信息的质量。优化器统计信息顾问维护着一组规则,这些规则体现了基于当前功能集的 Oracle 最佳实践。通过这种方式,顾问始终能为统计信息收集提供最新的建议。

另请参见

  • 《Oracle AI 数据库:开始使用性能调优》和《Oracle AI 数据库 SQL 调优指南》了解如何收集和管理统计信息
  • 《Oracle AI 数据库 PL/SQL 包和类型参考》了解 DBMS_STATS

Optimizer Hints(优化器提示)

提示是 SQL 语句中的一段注释,用作给优化器的指令。

有时,应用程序设计人员掌握了比优化器可用的更多关于特定应用程序数据的信息,因此能够选择更有效的方式来运行 SQL 语句。应用程序设计人员可以在 SQL 语句中使用提示来指定该语句应该如何运行。以下示例说明了提示的使用。

示例 10-2:带有 FIRST_ROWS 提示的 SELECT 执行计划

假设您的交互式应用程序运行一个返回 50 行的查询。该应用程序最初只提取查询的前 25 行以呈现给最终用户。您希望优化器生成一个尽可能快获取前 25 条记录的计划,从而避免用户被迫等待。您可以使用提示将此指令传递给优化器,如下面的 SELECT 语句及其 AUTOTRACE 输出所示:

sql 复制代码
SELECT /*+ FIRST_ROWS(25) */ employee_id, department_id
FROM   hr.employees
WHERE  department_id > 50;

------------------------------------------------------------------------
| Id | Operation                    | Name              | Rows | Bytes
------------------------------------------------------------------------
|  0 | SELECT STATEMENT             |                   | 26   | 182
|  1 |  TABLE ACCESS BY INDEX ROWID | EMPLOYEES         | 26   | 182
|* 2 |   INDEX RANGE SCAN           | EMP_DEPARTMENT_IX |      |
------------------------------------------------------------------------

在此示例中,执行计划显示优化器选择了 employees.department_id 列上的一个索引,以查找部门 ID 大于 50 的 employees 的前 25 行。优化器使用从索引检索到的 rowid 从 employees 表中检索记录并将其返回给客户端。第一条记录的检索基本上是即时的。

示例 10-3:不带提示的 SELECT 执行计划

假设您执行同一条语句,但不带优化器提示:

sql 复制代码
SELECT employee_id, department_id
FROM   hr.employees
WHERE  department_id > 50;
 
------------------------------------------------------------------------
| Id | Operation              | Name              | Rows | Bytes | Cos
------------------------------------------------------------------------
|  0 | SELECT STATEMENT       |                   | 50   | 350   |
|* 1 |  VIEW                  | index $_join $_001  | 50   | 350   |
|* 2 |   HASH JOIN            |                   |      |       |
|* 3 |    INDEX RANGE SCAN    | EMP_DEPARTMENT_IX | 50   | 350   |
|  4 |    INDEX FAST FULL SCAN| EMP_EMP_ID_PK     | 50   | 350   |

在这种情况下,执行计划连接两个索引以尽快返回所请求的记录。优化器没有像示例 10-2 那样反复地在索引和表之间切换,而是选择对 EMP_DEPARTMENT_IX 进行范围扫描,找到部门 ID 大于 50 的所有行,并将这些行放入一个哈希表中。然后优化器选择读取 EMP_EMP_ID_PK 索引。对于该索引中的每一行,它都会探测哈希表以找到部门 ID。

在这种情况下,数据库无法将第一行返回给客户端,直到对 EMP_DEPARTMENT_IX 的索引范围扫描完成。因此,这个生成的计划返回第一条记录会花费更长的时间。与示例 10-2 中通过索引 rowid 访问表的计划不同,此计划使用多块 I/O,从而产生大量读取。这些读取使得整个结果集的最后一行能够更快地被返回。

另请参见

《Oracle AI 数据库 SQL 调优指南》了解如何使用优化器提示


Overview of SQL Processing(SQL 处理概述)

本节解释 Oracle AI 数据库如何处理 SQL 语句。具体而言,本节说明了数据库创建对象时的 DDL 处理、修改数据时的 DML 处理以及检索数据的查询处理方式。

  • SQL 处理的阶段

    SQL 处理的一般阶段是解析、优化、行源生成和执行。根据语句的不同,数据库可能会省略其中的某些步骤。

  • DML 与 DDL 处理的差异

    Oracle AI 数据库处理 DDL 与处理 DML 的方式不同。


Stages of SQL Processing(SQL 处理的阶段)

SQL 处理的一般阶段是解析、优化、行源生成和执行。根据语句的不同,数据库可能会省略其中的某些步骤。

下图描述了这些一般阶段:

Figure 10-3 Stages of SQL Processing(图10-3 SQL 处理的阶段)

  • SQL 解析

    SQL 处理的第一阶段是 SQL 解析。此阶段涉及将 SQL 语句的各个片段分离到可由其他例程处理的数据结构中。

  • SQL 优化

    查询优化是选择执行 SQL 语句的最有效方式的过程。

  • SQL 行源生成

    行源生成器是这样一种软件:它从优化器接收最佳执行计划,并生成一个可供数据库其余部分使用的迭代计划,称为查询计划。

  • SQL 执行

    在执行期间,SQL 引擎执行由行源生成器生成的树中的每个行源。这是 DML 处理中唯一必须执行的步骤。


SQL Parsing(SQL 解析)

SQL 处理的第一阶段是 SQL 解析。此阶段涉及将 SQL 语句的各个片段分离到可由其他例程处理的数据结构中。

当应用程序发出 SQL 语句时,它会向数据库发出一个解析调用,以准备该语句以便执行。解析调用会打开或创建一个游标,游标是会话特定私有 SQL 区的句柄,其中保存了解析后的 SQL 语句和其他处理信息。游标和私有 SQL 区位于程序全局区中。

在解析调用期间,数据库会执行以下检查:

  • 语法检查
  • 语义检查
  • 共享池检查

前述检查可识别在语句执行之前能发现的错误。某些错误无法通过解析捕获。例如,数据库只有在语句执行期间才会遇到死锁或数据转换错误。

对于在解析阶段因 ORA-00600 错误而失败的 SQL 语句,数据库会尝试自动错误缓解。ORA-00600 是一个严重错误。它表明某个进程遇到了低级别、意外的情况。当一条 SQL 语句在解析阶段遇到此错误而失败时,自动错误缓解会捕获它并尝试解决该情况。如果找到了解决方案,数据库会生成一个 SQL 补丁来调整 SQL 执行计划。如果此补丁能使解析成功完成,则不会引发 ORA-00600 错误。应用程序不会看到任何异常。

另请参见


SQL Optimization(SQL 优化)

查询优化是选择执行 SQL 语句的最有效方式的过程。

数据库根据收集到的关于所访问实际数据的统计信息来优化查询。优化器使用行数、数据集大小及其他因素来生成可能的执行计划,为每个计划分配一个数值成本。数据库使用成本最低的计划。

对于每条唯一的 DML 语句,数据库至少必须执行一次硬解析,并在此解析期间进行优化。DDL 永远不会被优化,除非它包含一个需要优化的 DML 组件,例如子查询。

另请参见

  • 优化器概述
  • 《Oracle AI 数据库 SQL 调优指南》了解查询优化器的详细信息

SQL Row Source Generation(SQL 行源生成)

行源生成器是这样一种软件:它从优化器接收最佳执行计划,并生成一个可供数据库其余部分使用的迭代计划,称为查询计划。

查询计划采用一系列步骤组合的形式。每一步都返回一个行集。此集合中的行要么被下一步使用,要么在最后一步返回给发 SQL 语句的应用程序。

行源是由执行计划中的一个步骤返回的行集,以及一个可以迭代处理行的控制结构。行源可以是表、视图,也可以是连接或分组操作的结果。


SQL Execution(SQL 执行)

在执行期间,SQL 引擎执行由行源生成器生成的树中的每个行源。这是 DML 处理中唯一必须执行的步骤。

在执行期间,如果数据不在内存中,则数据库会将数据从磁盘读入内存。数据库还会获取必要的锁和闩锁以确保数据完整性,并记录执行 SQL 期间所做的任何更改。处理 SQL 语句的最后一个阶段是关闭游标。

如果数据库配置了内存列存储(IM 列存储),那么数据库会在可能的情况下将查询透明地路由到 IM 列存储,否则路由到磁盘和数据库缓冲区高速缓存。单个查询也可以同时使用 IM 列存储、磁盘和缓冲区高速缓存。例如,一个查询可能会连接两个表,其中只有一个表缓存在 IM 列存储中。

另请参见

  • 内存列存储区
  • 《Oracle AI 数据库 SQL 调优指南》了解执行计划和 EXPLAIN PLAN 语句的详细信息

Differences Between DML and DDL Processing(DML 与 DDL 处理的差异)

Oracle AI 数据库处理 DDL 与处理 DML 的方式不同。

例如,当您创建一张表时,数据库不会优化 CREATE TABLE 语句。相反,Oracle AI 数据库会解析该 DDL 语句并执行命令。

与 DDL 不同,大多数 DML 语句都有一个查询组件。在查询中,执行游标会将查询生成的行放入结果集。

数据库可以一次提取结果集的一行,也可以成组提取。在提取过程中,数据库会选择行,并且如果查询要求排序,则会对行进行排序。每次连续的提取都会检索结果集中的下一行,直到提取完最后一行。

另请参见

《Oracle AI 数据库开发指南》了解如何处理 DDL、事务控制及其他类型的语句

相关推荐
jnrjian2 小时前
export partition 的par file
数据库·oracle
空中海2 小时前
Redis知识图谱和回顾
数据库·redis·知识图谱
不甘先生2 小时前
PostgreSQL 数据库基础一览表
数据库·postgresql
DBdoctor官方2 小时前
2026 DBA实测推荐:5款数据库管理工具 监控、SQL审核、AI能力横评
数据库·sql·dba
qq_196976173 小时前
硬核项目管理:Gemini境像站驱动的WBS自动分解、关键路径识别与风险登记册生成(国内免费镜像实测)
数据库
迷枫7123 小时前
DM8 读写分离集群学习总结:从部署规划到扩容排查
数据库·学习
yuzhiboyouye3 小时前
聚合与分组统计 (GROUP BY)常用于web前端什么场景中
数据库
AllData公司负责人3 小时前
亲测丝滑,体验跃迁|AllData通过集成开源项目StreamPark,实时流任务调度更省心!
java·大数据·数据库·人工智能·算法·实时计算·实时开发平台
可涵不会debug3 小时前
工业大数据时序数据库选型方法论:核心指标与技术适配分析
大数据·数据库·时序数据库