---
title: 如何检查大查询整体情况 -OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于如何检查大查询整体情况 相关的常见问题和使用技巧，帮助您快速解决如何检查大查询整体情况 的难题。
---
切换语言

- 简体中文
- English

划线反馈

# 如何检查大查询整体情况

更新时间：2023-11-14 03:16

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x 内容类型：How-to  

OceanBase 数据库中耗时长的 SQL 称为大查询。本文介绍大查询的资源分配机制以及查询方法。

用户发给 observer 进程的 SQL 语句中，可以分为两类：一类 SQL 访问和操作的数据量小，所以执行很快；另一类 SQL 要访问大量的数据或者要写入大量数据，所有执行耗时长。耗时长的 SQL 称为大查询。

默认情况下，OceanBase 数据库的配置项 `large_query_threshold` 定义了以查询时长作为维度的大查询判别方式，默认为 100 ms，即查询时间超过 100 ms 的查询被认为是大查询。此外，`large_query_worker_percentage` 定义了大查询可以使用的工作线程数量，默认为 30%。有关以上配置项的详细信息，请参见《OceanBase 数据库参考指南》中的 **系统配置项** 章节。

## 适用版本

OceanBase 数据库所有版本。

## 大查询资源分配机制

当同时存在小查询和大查询时，OceanBase 数据库会把 30% 的 CPU 时间用于处理大查询。

对于 OceanBase 数据库 V2.X 版本，还不能精确控制大查询的 CPU 占用，observer 进程实际上是控制用来处理大查询的活跃线程数以限制 CPU 使用。大查询只能使用这个租户活跃线程的 30%。

#### 说明

租户的工作线程可能是正常执行的状态，也可能是被挂起的状态，没有挂起的线程就是活跃线程。

observer 进程根据租户的 `cpu_count * cpu_quota_concurrency` 计算活跃线程数，这些线程在创建租户时就会被创建。例如，活跃线程 A 由于执行大查询被挂起，这时活跃线程就少了一个，作为补充，这个租户会额外再创建一个活跃线程。一个租户能创建的线程总数由 `cpu_count * workers_per_cpu_quota` 控制。当租户线程数到达上限后，新创建线程会失败，线程 A 不会被挂起，以保持活跃线程数始终不变。

有关 `cpu_quota_concurrency` 与 `workers_per_cpu_quota` 的详细信息，请参见《OceanBase 数据库 参考指南》中的 **系统** **配置项** 章节。

## 通过 dump tenant 查询

在 OBServer 安装目录执行以下命令查询 `observer.log` 日志。

```unknow
[admin@hostname ~]$ cd /home/admin/oceanbase/log
[admin@hostname log]$ grep 'dump tenant.*tenant={id:1002' observer.log| sed "s/,/\n/g"

```

示例如下。

```unknow
[2020-12-16 15:29:24.640442] INFO  [SERVER.OMT] ob_multi_tenant.cpp:806 [31771][3104][Y0-0000000000000000] [lt=24] [dc=0] dump tenant info(tenant={id:1002
compat_mode:0
unit_min_cpu:"3.000000000000000000e+00"
unit_max_cpu:"3.000000000000000000e+00"
slice:"0.000000000000000000e+00"
slice_remain:"0.000000000000000000e+00"
token_cnt:12
ass_token_cnt:12
lq_tokens:3
used_lq_tokens:0
stopped:false
idle_us:1709164
recv_hp_rpc_cnt:2
recv_np_rpc_cnt:2
recv_lp_rpc_cnt:0
recv_mysql_cnt:314
recv_task_cnt:11
recv_large_req_cnt:0
tt_large_quries:12
actives:12
workers:12
nesting workers:7
lq waiting workers:0
req_queue:total_size=0 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=0 queue[5]=0
large queued:0
multi_level_queue:total_size=0 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=0 queue[5]=0 queue[6]=0 queue[7]=0
recv_level_rpc_cnt:cnt[0]=0 cnt[1]=0 cnt[2]=0 cnt[3]=0 cnt[4]=0 cnt[5]=0 cnt[6]=0 cnt[7]=0 })

```

关注以下两个字段的信息：

- `tt_large_quries`：表示 10s 内处理了多少个大查询 。
 - `lq waiting workers`：表示有多少个线程由于大查询被挂起。

## 通过查询 SQL 执行时间检查

OceanBase 数据库的 MySQL 租户和 Oracle 租户都可以通过 `gv$sql_audit` 视图来查看SQL 执行时间的分布情况，从而判断大查询占用的资源

- Oracle 租户

  ```unknow
  OBCLIENT> SELECT
  ROUND(AVG(AVG_EXECUTE_TIME),0) VALUE_AVG,
  ROUND(MAX(AVG_EXECUTE_TIME),0) VALUE_MAX,
  ROUND(MIN(AVG_EXECUTE_TIME),0) VALUE_MIN,
  ROUND(CUME_DIST(100) WITHIN GROUP(ORDER BY AVG_EXECUTE_TIME DESC),0) VALUE_PCT_OCCURRENCE_ABOVE_100MS,
  ROUND(CUME_DIST(5000000) WITHIN GROUP(ORDER BY AVG_EXECUTE_TIME DESC),0) VALUE_PCT_OCCURRENCE_ABOVE_5S
  FROM
  (
  SELECT SQL_ID,/*+READ_CONSISTENCY(WEAK), QUERY_TIMEOUT(100000000), PARALLEL(72)*/
  COUNT(1),
  ROUND(AVG(ELAPSED_TIME)) AVG_ELAPSED_TIME,
  ROUND(AVG(EXECUTE_TIME)) AVG_EXECUTE_TIME,
  ROUND(AVG(QUEUE_TIME)) AVG_QUEUE_TIME,
  ROUND(AVG(RETURN_ROWS)) AVG_RETURN_ROWS,
  ROUND(AVG(AFFECTED_ROWS)) AVG_AFFECTED_ROWS
  FROM GV$SQL_AUDIT
  WHERE TO_DATE('1970-01-01','YYYY-MM-DD') + (REQUEST_TIME / 1000000/86400)+TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24
  BETWEEN TO_DATE('2020-11-23 00:00:00','YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2020-11-25 00:00:00','YYYY-MM-DD HH24:MI:SS')
  GROUP BY SQL_ID
  ORDER BY ROUND(AVG(EXECUTE_TIME)) DESC
  );

  ```
 - MySQL 租户

  ```unknow
  OBCLIENT> SELECT
  ROUND(AVG(AVG_EXECUTE_TIME),0) VALUE_AVG,
  ROUND(MAX(AVG_EXECUTE_TIME),0) VALUE_MAX,
  ROUND(MIN(AVG_EXECUTE_TIME),0) VALUE_MIN,
  ROUND(CUME_DIST() OVER (ORDER BY AVG_EXECUTE_TIME DESC),0) VALUE_PCT_OCCURRENCE_ABOVE_100MS,
  ROUND(CUME_DIST() OVER (ORDER BY AVG_EXECUTE_TIME DESC),0) VALUE_PCT_OCCURRENCE_ABOVE_5S
  FROM
  (
  SELECT SQL_ID,/*+READ_CONSISTENCY(WEAK), QUERY_TIMEOUT(100000000), PARALLEL(72)*/
  COUNT(1),
  ROUND(AVG(ELAPSED_TIME)) AVG_ELAPSED_TIME,
  ROUND(AVG(EXECUTE_TIME)) AVG_EXECUTE_TIME,
  ROUND(AVG(QUEUE_TIME)) AVG_QUEUE_TIME,
  ROUND(AVG(RETURN_ROWS)) AVG_RETURN_ROWS,
  ROUND(AVG(AFFECTED_ROWS)) AVG_AFFECTED_ROWS
  FROM GV$SQL_AUDIT
  GROUP BY SQL_ID
  ORDER BY ROUND(AVG(EXECUTE_TIME)) DESC
  );

  ```

示例如下，其中 `value_pct_occurrence_above_100ms` 表示超过 100 ms 的查询，`value_pct_occurrence_above_5s` 表示超过 5s 的查询。

```unknow
+-----------+-----------+-----------+----------------------------------+-------------------------------+
| value_avg | value_max | value_min | value_pct_occurrence_above_100ms | value_pct_occurrence_above_5s |
+-----------+-----------+-----------+----------------------------------+-------------------------------+
|      6950 |    874275 |        17 |                                1 |                             1 |
+-----------+-----------+-----------+----------------------------------+-------------------------------+
1 row in set (0.63 sec)

```

Previous

[大查询线程的管理和调度机制](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000217863)

Next

[OceanBase 数据库集群内简单 SQL 语句因 -6004(lock_for_read need retry) 变慢的原因和解决方法](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002397820) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
