gpt4 book ai didi

使用 IDE 工具作为 SQL Developer 或 Toad 的 Oracle 并行查询行为

转载 作者:行者123 更新时间:2023-12-04 09:22:25 27 4
gpt4 key购买 nike

有一段时间我一直在努力抽出时间来写这个问题并尽可能地解释这个问题,所以请提前原谅我的长文。
我的环境:

  • 在 Red Hat 7(R.A.C 2 节点)上运行的 Oracle Database 12.2 - 每个节点 16CPU 和 64GB RAM。
  • Parallel Force Local 设置为 TRUE 以强制并行服务器进程只能在启动 SQL 语句的同一节点上执行。

  • 我们有一个非常大的数据库,其中包含许多服务于多个应用程序的模式。大多数应用程序实际上是PL/SQL中的批处理引擎,处理数以百万计的记录,因此出于性能原因,大多数大表都配置了PARALLEL DEGREE DEFAULT。表已分区并具有高级压缩。
    除了一些用于开发目的的报告 BI 工具外,许多最终用户还可以通过 SQL Developer 访问系统(仅在读取模式下)进行 QA 检查。我从不喜欢,但有时你必须接受事情的现状。
    为了控制一些事情,我设计了一个特定的登录触发器,它不仅涵盖审计功能,还涵盖传入 session 的某些方面:
  • 使用 SQL Developer 访问的最终用户可能只打开 2 个 session 。
  • 使用 SQL Developer 访问的最终用户运行立即执行 ALTER SESSION DISABLE PARALLEL QUERY。不幸的是,我知道有些用户正在自行激活它。 ALTER SESSION ENABLE/DISABLE PARALLEL QUERY 由 CREATE SESSION 特权或 CONNECT 角色继承,因此我对此无能为力。
  • 使用 SQL Developer 访问的最终用户被分配到特定的配置文件,在 CPU、磁盘读取等方面有限制。

  • 登录触发器允许或不允许基于一组附加规则的访问,但就问题而言,它们无关紧要。
    让我们看看在 SQL Developer 上运行的查询如何对启用 PARALLEL 的表进行处理:
    场景
    我有一个包含由不同分区分割的 80 亿条记录的表。用户使用 sql developer 登录并运行此查询
    SELECT COUNT(*) FROM MY_SCHEMA.MY_TABLE PARTITION ( MY_PARTITION ) ;

    183.940.801 rows
    由于该表没有索引,CBO 使用尽可能多的从属设备以并行方式运行 TABLE FULL SCAN。完成需要 6 秒。到目前为止,没有错。
    同时我正在监视 session (您可以在查询运行时看到所有 session 处于事件状态)
      INSTANCE     SID USERNAME             PROGRAM                                            SQL_ID               STATUS
    ---------- ------- -------------------- -------------------------------------------------- -------------------- --------
    2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) dtf8d89xg7muq ACTIVE
    2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) dtf8d89xg7muq ACTIVE
    2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) dtf8d89xg7muq ACTIVE
    2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) dtf8d89xg7muq ACTIVE
    2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) dtf8d89xg7muq ACTIVE
    2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) dtf8d89xg7muq ACTIVE
    2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) dtf8d89xg7muq ACTIVE
    2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) dtf8d89xg7muq ACTIVE
    2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) dtf8d89xg7muq ACTIVE
    2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) dtf8d89xg7muq ACTIVE
    2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) dtf8d89xg7muq ACTIVE
    2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) dtf8d89xg7muq ACTIVE
    2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) dtf8d89xg7muq ACTIVE
    2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) dtf8d89xg7muq ACTIVE
    2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) dtf8d89xg7muq ACTIVE
    2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) dtf8d89xg7muq ACTIVE
    2 1015 FDM_ADM_GRID SQL Developer dtf8d89xg7muq ACTIVE
    2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) dtf8d89xg7muq ACTIVE
    2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) dtf8d89xg7muq ACTIVE
    2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) dtf8d89xg7muq ACTIVE
    2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) dtf8d89xg7muq ACTIVE
    2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) dtf8d89xg7muq ACTIVE
    2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) dtf8d89xg7muq ACTIVE
    2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) dtf8d89xg7muq ACTIVE
    2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) dtf8d89xg7muq ACTIVE
    2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) dtf8d89xg7muq ACTIVE
    2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) dtf8d89xg7muq ACTIVE
    2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) dtf8d89xg7muq ACTIVE
    2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) dtf8d89xg7muq ACTIVE
    2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) dtf8d89xg7muq ACTIVE
    2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) dtf8d89xg7muq ACTIVE
    2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) dtf8d89xg7muq ACTIVE
    2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) dtf8d89xg7muq ACTIVE

    查询完成后
    SQL> r
    1* select inst_id as instance , sid, username, program, sql_id, status from gv$session where username = 'FDM_ADM_GRID'

    INSTANCE SID USERNAME PROGRAM SQL_ID STATUS
    ---------- ------- -------------------- -------------------------------------------------- -------------------- --------
    2 1015 FDM_ADM_GRID SQL Developer INACTIVE

    到现在为止还挺好。现在让我们在 SQL Developer 中运行另一个查询
    SELECT * FROM MY_SCHEMA.MY_TABLE partition ( MY_PARTITION ) fetch first 1000 rows only;
    该查询几乎立即检索前 1000 行。但是让我们看看数据库的不同
    运行时
    SQL> r
    1* select inst_id as instance , sid, username, program, sql_id, status from gv$session where username = 'FDM_ADM_GRID'

    INSTANCE SID USERNAME PROGRAM SQL_ID STATUS
    ---------- ------- -------------------- -------------------------------------------------- -------------------- --------
    2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) 9jyvj64ag15mv ACTIVE
    2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) 9jyvj64ag15mv ACTIVE
    2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) 9jyvj64ag15mv ACTIVE
    2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) 9jyvj64ag15mv ACTIVE
    2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) 9jyvj64ag15mv ACTIVE
    2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) 9jyvj64ag15mv ACTIVE
    2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) 9jyvj64ag15mv ACTIVE
    2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) 9jyvj64ag15mv ACTIVE
    2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) 9jyvj64ag15mv ACTIVE
    2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) 9jyvj64ag15mv ACTIVE
    2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) 9jyvj64ag15mv ACTIVE
    2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) 9jyvj64ag15mv ACTIVE
    2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) 9jyvj64ag15mv ACTIVE
    2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) 9jyvj64ag15mv ACTIVE
    2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) 9jyvj64ag15mv ACTIVE
    2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) 9jyvj64ag15mv ACTIVE
    2 1015 FDM_ADM_GRID SQL Developer ACTIVE
    2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) 9jyvj64ag15mv ACTIVE
    2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) 9jyvj64ag15mv ACTIVE
    2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) 9jyvj64ag15mv ACTIVE
    2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) 9jyvj64ag15mv ACTIVE
    2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) 9jyvj64ag15mv ACTIVE
    2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) 9jyvj64ag15mv ACTIVE
    2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) 9jyvj64ag15mv ACTIVE
    2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) 9jyvj64ag15mv ACTIVE
    2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) 9jyvj64ag15mv ACTIVE
    2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) 9jyvj64ag15mv ACTIVE
    2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) 9jyvj64ag15mv ACTIVE
    2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) 9jyvj64ag15mv ACTIVE
    2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) 9jyvj64ag15mv ACTIVE
    2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) 9jyvj64ag15mv ACTIVE
    2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) 9jyvj64ag15mv ACTIVE
    2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) 9jyvj64ag15mv ACTIVE
    查询完成后,我再次检查,但是现在所有从站都还在那里并且处于 ACTIVE 状态。我会认为一旦 QC 完成并标记为非事件状态,Oracle 就会关闭所有从属进程。但它没有
      `INSTANCE     SID USERNAME             PROGRAM`                                            SQL_ID               STATUS
    ---------- ------- -------------------- -------------------------------------------------- -------------------- --------
    2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) 9jyvj64ag15mv ACTIVE
    2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) 9jyvj64ag15mv ACTIVE
    2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) 9jyvj64ag15mv ACTIVE
    2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) 9jyvj64ag15mv ACTIVE
    2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) 9jyvj64ag15mv ACTIVE
    2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) 9jyvj64ag15mv ACTIVE
    2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) 9jyvj64ag15mv ACTIVE
    2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) 9jyvj64ag15mv ACTIVE
    2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) 9jyvj64ag15mv ACTIVE
    2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) 9jyvj64ag15mv ACTIVE
    2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) 9jyvj64ag15mv ACTIVE
    2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) 9jyvj64ag15mv ACTIVE
    2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) 9jyvj64ag15mv ACTIVE
    2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) 9jyvj64ag15mv ACTIVE
    2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) 9jyvj64ag15mv ACTIVE
    2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) 9jyvj64ag15mv ACTIVE
    2 1015 FDM_ADM_GRID SQL Developer INACTIVE
    2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) 9jyvj64ag15mv ACTIVE
    2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) 9jyvj64ag15mv ACTIVE
    2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) 9jyvj64ag15mv ACTIVE
    2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) 9jyvj64ag15mv ACTIVE
    2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) 9jyvj64ag15mv ACTIVE
    2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) 9jyvj64ag15mv ACTIVE
    2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) 9jyvj64ag15mv ACTIVE
    2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) 9jyvj64ag15mv ACTIVE
    2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) 9jyvj64ag15mv ACTIVE
    2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) 9jyvj64ag15mv ACTIVE
    2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) 9jyvj64ag15mv ACTIVE
    2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) 9jyvj64ag15mv ACTIVE
    2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) 9jyvj64ag15mv ACTIVE
    2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) 9jyvj64ag15mv ACTIVE
    2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) 9jyvj64ag15mv ACTIVE
    2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) 9jyvj64ag15mv ACTIVE

    只要 session 保持打开状态,QC 将保持不事件状态,而从站将保持事件状态,因此尽管它们没有做任何事情,但它们仍然算作并行服务器。 session 关闭或用户运行另一个查询让我注意并行使用中的更改。但是如果用户去喝咖啡,或者去发布或者正在做其他事情,就不会有任何东西。
    有 100 多个用户同时工作,您可能会感到头疼。我不得不设计一些解决方法:
  • 我必须在触发器内创建一个新控件来识别 QC 与处于 ACTIVE 状态的从属设备的非事件时间,以便确定用户已经打开了多少 session 。
  • 在 1 小时的窗口时间后,我必须创建一个清理过程以断开此状态下的 session
  • 我不能在 Profiles 中使用限制 session ,因为它们在 QC 或 SLAVES 之间没有区别。
  • 无论我配置了多少东西,有时我都会用完并行进程,如果在工作时间执行批处理(这种情况经常发生),我有时会面临那些重要进程缺乏并行可用性的问题,因为这些重要进程占用的从属数量很多非事件 session 。

  • 我的问题如下:
  • 当 QC 已经完成时,为什么从站仍然处于 ACTIVE 状态?难道不应该在 QC 传送结果后立即终止从站吗?
  • 为什么在 SQLPLUS 和 Java 池解决方案(如 SAP 业务对象)中运行非常相似的查询时不会发生这种行为?
  • 有没有办法禁用最终用户的并行功能,无论他们尝试通过 ENABLE PARALLEL QUERY 还是通过 HINTS 激活它们?

  • 我为这么长的问题道歉,但我不想留下任何东西。
    我真的很感激任何对此的见解。
    谢谢你们。

    最佳答案

    您的查询并未真正完成。尽管您的查询仅提取前 1000 行,但 SQL Developer 仅提取这 1000 行中的前 50 行。在您滚动到最后一行之前,IDE 不会关闭光标。一旦您检索到所有数据,这些并行进程就会消失。确保您看到“All Rows Fetched: 1000 in X seconds”,而不是“”Fetched 50 rows in Y seconds”。(我希望 SQL Developer 能让它在视觉上更明显,还有其他行在等待。)你不会在 SQL*Plus 中看到这个问题,因为 SQL*Plus 总是抓取所有行。
    当仅获取前 N 行时,这些并行进程处于“事件状态”但不执行任何操作。您应该能够忽略这些 session ,因为它们没有使用任何重要资源。
    如果您只担心并行 session 的数量,您可能需要调整您的期望。我曾经和您处于相同的情况 - 不断告诉用户他们的(不完整的)查询正在占用所有并行 session 。最终,我发现这只是一个问题,因为我创造了一种人为的稀缺资源。 Oracle 并行进程通常是轻量级的,并且数据库可以支持比大多数人想象的更多的并行进程。
    PARALLEL_MAX_SERVERS、PARALLEL_THREADS_PER_CPU 和 CPU_COUNT 的参数值是多少?查看 PARALLEL_MAX_SERVERS 的默认值.根据手册,默认号码是:PARALLEL_MAX_SERVERS = PARALLEL_THREADS_PER_CPU * CPU_COUNT * concurrent_parallel_users * 5 .
    大多数 DBA 看到并行线程的最大数量为数百,然后会出现 panic ,然后减少该数量。然后我们开始对开发人员大喊大叫,因为他们使用了人为限制的不重要的资源。相反,我们应该将数字恢复到默认值,而忽略随机并行 session 。如果用户没有超过 IO 或 CPU 限制,那么他们使用多少并行线程就无关紧要。
    (除了防止大量并行查询 session 使用的可能异常(exception)。将您的用户放在不同的配置文件中,并将他们的 SESSIONS_PER_USER 设置为几十个。不要将其限制为 1 或 2。IDE 需要额外的 session 用于多个选项卡、后台进程获取元数据和调试 session 。如果您将限制设置为 2,您的开发人员将无法正确使用 IDE。)

    编辑(回复评论)
    我不确定您是否可以深入了解 query coordinator 的状态。 . QC 会做几件事,但理想情况下,它会在大部分时间处于空闲状态,而并行 session 处理大部分工作。
    对于生产者/消费者模型,一半的并行 session 可能正在接收数据但实际上并没有做任何事情——就像它们只是某些操作中的内存结构。并行 session 可能会在事件和非事件之间切换,因为并非所有步骤都需要相同数量的 session 。但是我们不希望 Oracle 在中间关闭 session ,因为稍后可能需要它们,我们不想浪费时间打开和关闭 session 。
    影响并行度的因素有很多,但据我所知,增加PARALLEL_MAX_SERVERS不会影响单个语句请求的并行服务器数量。 (但如果语句已经要求比最大值更多的服务器,增加参数可能会影响分配的 session 数)。
    可能感觉 SQL 语句只是随机抓取所有并行 session ,但最终 DOP 计算几乎总是遵循确定性规则。只是规则如此复杂,很难说它是如何运作的。例如,一个常见的混淆点是,每当查询添加排序或分组时,并行 session 的数量就会增加一倍。

    关于使用 IDE 工具作为 SQL Developer 或 Toad 的 Oracle 并行查询行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63076728/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com