【问题标题】:Oracle 11.2 has a delay of 2 seconds for simple SQL at random timesOracle 11.2 随机时间对简单 SQL 有 2 秒的延迟
【发布时间】:2015-04-10 15:48:02
【问题描述】:

一个简单的表连接通常在 0.0XX 秒内完成,有时在 2.0XX 秒内完成(根据 PL/SQL Developer SQL 执行)。从 SQL Plus 运行时仍然会发生这种情况。

如果我运行 SQL 10 次,8 次运行良好,2 次运行 2 秒以上。

这是在 Centos 7 上为 Linux x86_64 全新安装的 Oracle 11.2.0.4。 我已经安装了 Oracle 推荐的补丁:

  • 补丁 19769489 - 数据库补丁集更新 11.2.0.4.5(包括 CPUJan2015)
  • 补丁 19877440 - Oracle JavaVM 组件 11.2.0.4.2 数据库 PSU(2015 年 1 月)

修补后没有变化。

这两张桌子有: LNK_PACK_REP:13 行 包:6 行

在 SQL Plus 中,我启用了所有统计信息并多次运行 SQL。只是时间不时地从 0.1 变为 2.1。如果我将 0.1 秒内的跑步与 2.1 秒内的跑步进行比较,则不会更改其他统计数据。该服务器具有 16 Gb RAM 和 8 个 CPU 内核。服务器负载低于 0.1(暂时没有用户使用服务器)。

输出:

SQL> select PACKAGE_ID, id, package_name from LNK_PACK_REP LNKPR INNER JOIN PACKAGES P ON LNKPR.PACKAGE_ID = P.ID;

PACKAGE_ID ID PACKAGE_NAME


     3          3 RAPOARTE
     3          3 RAPOARTE
   121        121 VANZARI
   121        121 VANZARI
   121        121 VANZARI
     2          2 PACHETE
     2          2 PACHETE
     1          1 DEPARTAMENTE
     1          1 DEPARTAMENTE
    81         81 ROLURI
    81         81 ROLURI

PACKAGE_ID ID PACKAGE_NAME


   101        101 UTILIZATORI
   101        101 UTILIZATORI

已选择 13 行。

经过:00:00:02.01

执行计划

计划哈希值:2671988802

--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name              | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                   |    13 |   351 |     3   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR         |                   |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)   | :TQ10002          |    13 |   351 |     3   (0)| 00:00:01 |  Q1,02 | P->S | QC (RAND)  |
|*  3 |    HASH JOIN            |                   |    13 |   351 |     3   (0)| 00:00:01 |  Q1,02 | PCWP |            |
|   4 |     PX RECEIVE          |                   |     6 |    84 |     2   (0)| 00:00:01 |  Q1,02 | PCWP |            |
|   5 |      PX SEND HASH       | :TQ10001          |     6 |    84 |     2   (0)| 00:00:01 |  Q1,01 | P->P | HASH       |
|   6 |       PX BLOCK ITERATOR |                   |     6 |    84 |     2   (0)| 00:00:01 |  Q1,01 | PCWC |            |
|   7 |        TABLE ACCESS FULL| PACKAGES          |     6 |    84 |     2   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|   8 |     BUFFER SORT         |                   |       |       |            |          |  Q1,02 | PCWC |            |
|   9 |      PX RECEIVE         |                   |    13 |   169 |     1   (0)| 00:00:01 |  Q1,02 | PCWP |            |
|  10 |       PX SEND HASH      | :TQ10000          |    13 |   169 |     1   (0)| 00:00:01 |        | S->P | HASH       |
|  11 |        INDEX FULL SCAN  | UNQ_PACK_REP      |    13 |   169 |     1   (0)| 00:00:01 |        |      |            |
--------------------------------------------------------------------------------------------------------------------------

谓词信息(由操作id标识):

3 - 访问("LNKPR"."PACKAGE_ID"="P"."ID")

注意

  • 用于此语句的动态采样 (level=2)

统计

     24  recursive calls
      0  db block gets
     10  consistent gets
      0  physical reads
      0  redo size
    923  bytes sent via SQL*Net to client
    524  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      4  sorts (memory)
      0  sorts (disk)
     13  rows processed

表1结构:

-- Create table
create table PACKAGES
(
  id           NUMBER(3) not null,
  package_name VARCHAR2(150),
  position     NUMBER(3),
  activ        NUMBER(1)
)
tablespace UM
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table PACKAGES
  add constraint PACKAGES_ID primary key (ID)
  using index 
  tablespace UM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate indexes 
create index PACKAGES_ACTIV on PACKAGES (ID, ACTIV)
  tablespace UM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

表2结构:

-- Create table
create table LNK_PACK_REP
(
  package_id NUMBER(3) not null,
  report_id  NUMBER(3) not null
)
tablespace UM
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table LNK_PACK_REP
  add constraint UNQ_PACK_REP primary key (PACKAGE_ID, REPORT_ID)
  using index 
  tablespace UM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate indexes 
create index LNK_PACK_REP_REPORT_ID on LNK_PACK_REP (REPORT_ID)
  tablespace UM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

在 SQL Monitor 的 Oracle Enterprise Manager 中,我可以看到多次运行的 SQL。所有runns都有“数据库时间”0.0s(如果我悬停列表,则低于10微秒)和“持续时间”0.0s用于正常运行,2.0s用于延迟。 如果我为 2.0s 运行受监控的 SQL 执行,我有:

  • 持续时间:2.0s
  • 数据库时间:0.0s
  • PL/SQL 和 Java:0.0
  • 等待活动:%(此处无数字)
  • 缓冲区获取:10
  • IO 请求:0
  • IO 字节数:0
  • 获取调用:2
  • 并行:4

这些数字与快速运行一致,但持续时间甚至小于数据库时间(10,163 微秒数据库时间和 3,748 微秒持续时间),如果没有鼠标悬停,则两者都显示为 0.0 秒。

我不知道还要检查什么。

【问题讨论】:

  • 并行查询?我会在这么小的桌子上禁用它。
  • 这是默认设置。我没有 SQL 提示,也没有更改与并行执行相关的任何设置。桌子会变大。原始 SQL 有 10 个表连接,但我已经设法将这个问题减少到只有 2 个表连接,结果没有变化。
  • 您确认延迟是在数据库端而不是在 SQL*Plus 客户端吗?
  • 在较大的表上运行 PQ 没有问题,但我会尝试消除它作为导致此问题的原因,因为它需要查询前执行检查点以及其他问题。
  • 我假设您已经检查了警报日志以查找诸如等待日志切换的日志写入器之类的内容?

标签: linux database oracle delay


【解决方案1】:

无法在几秒钟内有意义地调整并行查询。它们专为长时间处理大量数据的查询而设计。

使用小数据集优化并行语句的最佳方法是暂时禁用它:

alter system set parallel_max_servers=0;

(这是在工作站而不是服务器上开发优势的一个很好的例子。在服务器上,这种变化会影响到每个人,你甚至可能没有运行命令的权限。)

查询可能很简单,但并行性在后台增加了很多复杂性。

很难确切地说为什么它变慢了。如果您有 SQL 监控报告,等待事件可能会有所帮助。但即使是这些数字也可能只是像“CPU”这样的通用等待。并行查询有很多开销,期望资源密集型、长时间运行的查询。以下是一些类型的开销,可以解释这 2 秒的来源:

  1. 动态采样 - 并行性可能会自动导致动态采样,即从表中读取数据。虽然dynamic sampling used for this statement (level=2) 可能只是意味着缺少优化器统计信息。
  2. OS 线程启动 - SQL 语句可能需要额外启动 8 个 OS 线程,并准备大量内存来保存所有中间数据。也许 参数PARALLEL_MIN_SERVERS 可以帮助避免花费一些时间来创建这些线程。
  3. 附加监控 - 自动监控并行语句,这需要递归 SELECT 和 INSERT。
  4. 缓存 - 并行查询通常直接从磁盘读取并跳过读取和写入缓冲区缓存。何时缓存数据的规则很复杂且没有记录。
  5. 降级 - 找到正确的并行度很复杂。例如,我编制了39 factors that influence the DOP 的列表。其中一个可能导致降级,使某些查询速度快而其他查询速度慢。

而且我想不出还有很多其他类型的开销。并行性非常适合大规模提高大型操作的运行时间。但它不适用于微小的查询。

【讨论】:

    【解决方案2】:

    延迟是由于 David Aldridge 和 Jon Heller 建议的并行性,但我不同意 Jon Heller 提出的禁用所有查询并行性的解决方案(在系统级别)。您可以使用“alter session”来禁用它并在运行大查询之前重新启用它。延迟的确切原因仍然未知,因为查询在 10 次运行中有 8 次快速完成,我预计会快速运行 10/10。

    【讨论】:

    • 将其设置在会话级别将是管理并行性的侵入性最小的方式。但请记住,语句提示可以覆盖会话值。如果这是由多个开发人员构建大型查询的大型程序的一部分,那么人们可能不可避免地会开始抛出并行提示。
    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多