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日

相关文章

  • Oracle 错误日志表及异常处理包详解 附源码

    让我详细讲解一下“Oracle 错误日志表及异常处理包详解 附源码”的完整攻略。 标题 什么是错误日志表及异常处理包? 在Oracle数据库中,错误日志表和异常处理包是管理和记录数据库出现异常和错误的重要工具。错误日志表可以记录数据库中出现的错误信息,并允许用户通过查询该表来分析和解决这些错误。异常处理包则提供了一系列的异常处理程序,它们可以在发生错误时自动…

    database 2023年5月21日
    00
  • SQL 计算同一组或分区的行之间的差

    计算同一组或分区的行之间的差,可以使用SQL中的窗口函数(Window Function)来实现。 窗口函数是一种特殊的SQL函数,可以在SELECT语句中对数据子集进行窗口化操作。窗口函数可以在不改变查询结果集的情况下,对查询结果进行比较、排序、聚合等操作。 常用的窗口函数有:ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()…

    database 2023年3月27日
    00
  • 宝塔Linux面板之好用免费的中文Linux VPS主机控制面板适合快速建站

    宝塔Linux面板简介 宝塔Linux面板是一个免费的服务器运维面板,适合于Linux服务器,提供了简单易用的管理界面,提供可视化的操作,便于新手用户快速上手,同时也能满足高级用户的使用需求。 宝塔Linux面板安装 安装宝塔Linux面板非常简单,只需要在Linux服务器上运行以下命令即可: curl -sSO http://download.bt.cn/…

    database 2023年5月22日
    00
  • 数据库查询优化(主从表的设计)

    数据库查询优化(主从表的设计)完整攻略 在大型网站或应用中,数据库查询优化至关重要。当查询数据量大、并发高的时候,数据库的性能会成为瓶颈,降低整个应用的响应速度。为了解决这一问题,可以采用主从表的设计来进行数据库查询优化。 什么是主从表设计? 主从表设计是一种数据库查询优化的方法,它是将数据存储在两个或多个表中,并利用主表和从表之间的关系进行查询数据的操作。…

    database 2023年5月19日
    00
  • Redis分布式锁如何实现续期

    在 Redis 分布式锁中,为了避免锁超时导致其他进程获取到锁,需要对锁进行续期操作。实现 Redis 分布式锁的续期可通过以下几个步骤来完成: 在获取锁时,设置锁的过期时间,例如 60 秒。 在获取锁成功之后,启动一个协程或者开启一个定时任务,每隔一段时间(例如 30 秒)对锁进行续期操作。可以通过设置一个新的过期时间来实现续期,例如 60 秒。 锁的续期…

    database 2023年5月22日
    00
  • 通过Jedis操作Redis

      package com.yh; import org.junit.After; import org.junit.Before; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.params.SetParams; import java…

    Redis 2023年4月11日
    00
  • mysql中TIMESTAMPDIFF案例详解

    MySQL中TIMESTAMPDIFF函数的用法 在MySQL中,TIMESTAMPDIFF函数可以用来计算两个日期或时间之间的差值,以指定的时间单位作为结果。下面是TIMESTAMPDIFF函数的用法及示例。 语法 TIMESTAMPDIFF(unit, datetime_expression1, datetime_expression2) 其中,unit…

    database 2023年5月22日
    00
  • PHP编译安装中遇到的两个错误和解决方法

    下面是“PHP编译安装中遇到的两个错误和解决方法”的完整攻略。 背景描述 在使用 PHP 进行开发时,有时候需要进行编译安装。但是,在这个过程中,可能会遇到一些错误。本文将针对其中比较常见的两个错误进行分析,并给出解决方案。 错误一:configure: error: Cannot find OpenSSL’s libraries 在编译 PHP 时,执行 …

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