Oracle中基于hint的3种执行计划控制方法详细介绍

首先,我们需要明确什么是执行计划。执行计划是数据库在执行SQL语句时的一种预估性的计划,它会告诉我们数据库在执行该SQL语句时的具体操作步骤和执行顺序。通过调整执行计划,我们可以优化SQL语句的性能。

在Oracle数据库中,基于hint的3种执行计划控制方法包括:

  1. 使用INLINE提升性能

INLINE是一个hint,它可以让Oracle把一些短小简单的SQL代码嵌入到调用它们的SQL块中,可以减少操作的时间和I/O等待时间。这个hint应该只用于简单的SQL语句,如:

SELECT /*+ INLINE(w) */ w.worker_id, w.first_name, w.last_name, w.job_title
FROM workers w
WHERE w.job_title = 'Manager'
ORDER BY w.last_name, w.first_name;

这段代码中,我们使用了INLINE hint来嵌入SQL语句,提升查询的性能。

  1. 使用INDEX提示强制使用索引

有时候,Oracle的优化器会决定不使用索引来执行查询语句,从而导致性能下降。在这种情况下,我们可以使用INDEX hint来强制使用索引,如:

SELECT /*+ INDEX(w, workers_idx) */ w.worker_id, w.first_name, w.last_name, w.job_title
FROM workers w
WHERE w.job_title = 'Manager'
ORDER BY w.last_name, w.first_name;

这段代码中,我们使用了INDEX hint来强制使用名为workers_idx的索引,以提高查询性能。

  1. 使用FULL提示强制全表扫描

相比使用索引,有时候全表扫描可能更快。在这种情况下,我们可以使用FULL hint来强制进行全表扫描,如:

SELECT /*+ FULL(w) */ w.worker_id, w.first_name, w.last_name, w.job_title
FROM workers w
WHERE w.job_title = 'Manager'
ORDER BY w.last_name, w.first_name;

这段代码中,我们使用FULL hint来强制进行全表扫描,以提高查询性能。

以上就是基于hint的3种执行计划控制方法。在使用这些hint时,需要注意,最好只在知晓其效果后才使用。如果过度使用或误用这些hint,可能会导致SQL语句性能下降。同时也需要了解各个hint的语法和功能特点。

示例1:

原始查询语句如下:

SELECT w.worker_id, w.first_name, w.last_name, w.job_title
FROM workers w
WHERE w.job_title = 'Manager'
ORDER BY w.last_name, w.first_name;

查询计划如下:

Execution Plan  
----------------------------------------------------------
Plan hash value: 2005743770

---------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     4 |   192 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL | WORKERS |     4 |   192 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("JOB_TITLE"='Manager')

Statistics
-----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        747  bytes sent via SQL*Net to client
        573  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          4  rows processed

可以看到,执行计划是使用了全表扫描操作来执行查询。

现在我们使用FULL hint强制全表扫描,查询语句如下:

SELECT /*+ FULL(w) */ w.worker_id, w.first_name, w.last_name, w.job_title
FROM workers w
WHERE w.job_title = 'Manager'
ORDER BY w.last_name, w.first_name;

查询计划如下:

Execution Plan  
----------------------------------------------------------
Plan hash value: 2005743770

-------------------------------------------------------------
| Id  | Operation         | Name    | Rows | Bytes | Cost (%CPU)| Time    |
-------------------------------------------------------------
|   0 | SELECT STATEMENT  |         |    4 |   192 |     2   (0)| 00:00:01|
|   1 |  TABLE ACCESS FULL| WORKERS |    4 |   192 |     2   (0)| 00:00:01|
-------------------------------------------------------------

Statistics
-----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        747  bytes sent via SQL*Net to client
        573  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          4  rows processed

可以看到,执行计划并未发生变化,这说明本身就是最优执行计划。

示例2:

原始查询语句如下:

SELECT d.department_id, COUNT(w.worker_id)
FROM departments d
JOIN workers w ON w.department_id = d.department_id
WHERE d.department_name = 'Sales'
GROUP BY d.department_id;

查询计划如下:

Execution Plan  
----------------------------------------------------------
Plan hash value: 183478260

---------------------------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |            |     1 |    22 |     3   (0)| 00:00:01 |
|   1 |  SORT GROUP BY     |            |     1 |    22 |     3   (0)| 00:00:01 |
|*  2 |   HASH JOIN        |            |    14 |   308 |     2   (0)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| DEPARTMENTS|     1 |    11 |     1   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| WORKERS    |   107 |  2675 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("W"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")

Statistics
-----------------------------------------------------------
          0  recursive calls
          0  db block gets
         26  consistent gets
          0  physical reads
          0  redo size
        556  bytes sent via SQL*Net to client
        546  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

可以看到,执行计划使用了HASH JOIN操作,因为这个查询需要把两个大表进行连接。

现在我们使用INLINE hint嵌入到查询语句中,查询语句如下:

SELECT /*+ INLINE(d) */ d.department_id, COUNT(w.worker_id)
FROM departments d /*+ INLINE */ JOIN workers w /*+ INLINE */
    ON w.department_id = d.department_id
WHERE d.department_name = 'Sales' /*+ INLINE */
GROUP BY d.department_id;

查询计划如下:

Execution Plan  
----------------------------------------------------------
Plan hash value: 2362383159

------------------------------------------------------------
| Id  | Operation         | Name        | Rows | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |     1 |    30 |     3   (0)| 00:00:01 |
|   1 |  HASH GROUP BY    |             |     1 |    30 |     3   (0)| 00:00:01 |
|   2 |   NESTED LOOPS    |             |    14 |   420 |     2   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS   | WORKERS     |     7 |   161 |     1   (0)| 00:00:01 |
|*  4 |     INDEX UNIQUE  | WORKERS_PK  |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    TABLE ACCESS   | DEPARTMENTS |     2 |    22 |     1   (0)| 00:00:01 |
----------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("DEPARTMENT_NAME"='Sales')
   4 - access("W"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
   5 - filter("D"."DEPARTMENT_NAME"='Sales')

Note
-----
   - inline SQL tuning starts here

Statistics
-----------------------------------------------------------
          0  recursive calls
          0  db block gets
         18  consistent gets
          0  physical reads
          0  redo size
        556  bytes sent via SQL*Net to client
        546  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

可以看到,执行计划使用了NESTED LOOPS和HASH GROUP BY操作,从而使查询更快地运行。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Oracle中基于hint的3种执行计划控制方法详细介绍 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • MySQL数据库优化之索引实现原理与用法分析

    下面是针对“MySQL数据库优化之索引实现原理与用法分析”的完整攻略。 一、 索引的原理和作用 1.1 索引的原理 索引是一种特殊的数据结构,用于快速查找数据,从而提高数据的检索速度。MySQL中支持多种类型的索引,如B树索引、哈希索引、全文索引等。 常用的B树索引是一种平衡树结构,通过对数据进行分布式存储,将数据按照顺序排列,提高了查找数据的效率。 1.2…

    database 2023年5月19日
    00
  • php与php MySQL 之间的关系

    PHP和PHP MySQL是两个不同的技术,但它们在Web应用程序开发中紧密相关。在Web开发中,PHP主要用于服务器端编程,而PHP MySQL则用于数据库的管理和操作。 PHP是一种流行的通用脚本语言,用于创建动态Web页面和Web应用程序。它可以嵌入HTML中,可以接收HTML表单,并将表单数据发送到Web服务器进行处理。PHP运行在服务器端,它根据客…

    database 2023年5月22日
    00
  • 新手入门Mysql–sql执行过程

    新手入门MySQL – SQL执行过程 MySQL数据库是一种常用的关系型数据库管理系统,可以帮助我们储存和管理数据。本文将为新手讲解MySQL中SQL执行过程的完整攻略。 SQL执行过程 当我们向MySQL发送SQL语句时,MySQL会进行以下步骤来执行SQL语句: 词法分析:将SQL语句分解成一个个词组,如关键字、表名、列名等。 语法分析:将分解后的词组…

    database 2023年5月19日
    00
  • MySQL删除数据库(DROP DATABASE语句)

    MySQL中可以使用DROP DATABASE语句来删除一个数据库。 这个语句会删除数据库中的所有表和数据,所以在执行该语句前请务必慎重考虑。 使用方法如下: 进入MySQL命令行界面 切换到要删除的目标数据库,例如: USE database_name; 执行DROP DATABASE语句 DROP DATABASE database_name; 执行该语…

    MySQL 2023年3月9日
    00
  • Linux安装MySQL教程(二进制分发版)

    下面我详细讲解“Linux安装MySQL教程(二进制分发版)”的完整攻略。 1. 背景介绍 在Linux系统下进行MySQL的安装,有两种常见的方式:二进制分发版和源码编译版。本篇教程介绍的是MySQL的二进制分发版安装教程,适用于CentOS、RedHat等Linux系统。 2. 环境准备 在进行MySQL安装前,请确保你的Linux系统满足以下要求: 已…

    database 2023年5月22日
    00
  • mysql 8.0.12 安装配置教程

    MySQL 8.0.12 安装配置教程 MySQL是一个流行的开源关系型数据库管理系统,本文将介绍如何在Windows环境下安装配置MySQL 8.0.12版本,提供全面的安装过程展示。 步骤一:下载MySQL 8.0.12 MySQL官网提供了多个版本的Windows安装程序,我们选择MySQL Community Server 8.0.12版本的Wind…

    database 2023年5月22日
    00
  • 详解Java获取环境变量及系统属性的方法

    详解Java获取环境变量及系统属性的方法 简介 Java程序可以获取当前操作系统的环境变量和系统属性。环境变量指的是操作系统中设置的变量,它们可以影响程序的行为。系统属性指的是Java虚拟机提供的参数,它们可以影响Java程序的行为。获取环境变量以及系统属性的方法都可以通过System类来完成。 获取环境变量 使用System.getenv()方法可以获取所…

    database 2023年5月21日
    00
  • SQL – DELETE 语句

    下面是SQL-DELETE语句的详细攻略: 基本语法 SQL中DELETE语句用于从表中删除记录(行)。基本语法如下: DELETE FROM 表名 WHERE 条件; 其中,表名指定要删除记录的表名称,WHERE子句指定要满足的条件,只有满足条件的记录会被删除。如果不指定WHERE子句,则会删除表中所有记录。 实例一:删除指定条件的记录 假设有一个学生信息…

    database 2023年3月27日
    00
合作推广
合作推广
分享本页
返回顶部