【问题标题】:Oracle - Why is SELECT * FROM Foo; so slow?Oracle - 为什么是 SELECT * FROM Foo;太慢了?
【发布时间】:2011-09-22 21:10:48
【问题描述】:

我正在处理我们的 Web 应用程序的一些 Oracle 性能问题。我注意到似乎混淆了任何类型的测试的一件事是返回大量结果的简单查询仍然非常慢。一个例子是:

select * from TPM_PROJECTWORKGROUPS;

当我运行它时,我得到:

 5825 record(s) selected [Fetch MetaData: 0ms] [Fetch Data: 59s] 

 [Executed: 9/22/2011 1:52:38 PM] [Execution: 203ms] 

如果我理解正确,这意味着实际查询需要 203 毫秒才能运行,但需要 59 秒才能将该数据返回给客户端,在这种情况下是“获取”的意思吗?

我无权直接连接到数据库机器并在本地运行查询,但是可以安全地假设罪魁祸首是实际的网络带宽本身吗?这是有道理的,因为我在西雅图,服务器在纽约,但 5800 行仍然需要一分钟的吞吐量似乎相当慢。

对于 a) 确认网络带宽确实是问题和 b) 任何“陷阱”或检查为什么通过线路序列化数据如此缓慢的原因,是否有任何快速建议?谢谢!

基于评论的一些更新:

SELECT COUNT(*) FROM(从 TPM_PROJECTWORKGROUPS 中选择 *)t;

结果:

 1 record(s) selected [Fetch MetaData: 0ms] [Fetch Data: 0ms] 

 [Executed: 9/22/2011 2:16:08 PM] [Execution: 219ms] 

如果我尝试只选择一列:

从 TPM_PROJECTWORKGROUPS 中选择项目 ID;

结果:

已选择 5825 条记录 [Fetch MetaData: 0ms] [Fetch Data: 1m 0s]

[执行时间:2011 年 9 月 22 日下午 2:17:20] [执行时间:203 毫秒]

表架构:

项目 ID(编号) WORKGROUPID(编号)

【问题讨论】:

  • 您确定 TPM_PROJECTWORKGROUPS 是表而不是视图吗?
  • 一行的大小是多少?任何 CLOB/BLOB?
  • 试试SELECT COUNT(*) FROM (select * from TPM_PROJECTWORKGROUPS) t;看看有没有很大的不同
  • 表中有哪些数据?例如,如果表有一个大的文本字段或二进制数据,这可以解释缓慢的获取时间。尝试选择一列并查看性能
  • @Conrad Frix 这是一个很好的建议,但您应该解释一下,这两个查询之间的差异与获取的数据大小直接相关。

标签: sql database oracle networking oracle11g


【解决方案1】:

您使用什么 API 与数据库交互(SQL*Plus、JDBC、ODBC 等)?任何 API 都会有一些函数来指定在一次网络往返中要获取多少行(或多少数据)。例如,在 SQL*Plus 中,它是 set arraysize N。在 JDBC 中,它是 setFetchSize。其他 API 将具有类似的功能。如果您在 WAN 上,您通常希望通过增加每次网络往返获取的行数来最大程度地减少应用程序的繁琐程度。

同样,您可能会受益于通过网络传输更少的数据并将更多的逻辑推送到服务器。您实际上是否向用户显示包含 5800 行数据的网格?还是您确实获取该数据,然后在应用程序中执行一些处理(即对数据进行排序并显示前 100 行)?如果您可以将该处理推送到数据库并减少必须通过数据库传输的数据量,那么您的情况会好得多。

Oracle 可以选择配置 SDU 和 TDU 以及 SQL*Net 中的一些其他网络参数。不过,在您优化了获取大小并确保您尽可能少地提取数据之前,我不会开始研究这些选项。

【讨论】:

  • 现在,我正在使用使用 JDBC 的 Aqua Data Studio 运行它。我绝对会小心获取比我需要的更多的数据;在这种特殊情况下,我正在报告实际上/确实/需要显示大量数据。其中一些报告需要几分钟才能构建,但查询似乎在半秒内运行!令我惊讶的是,所有时间都用于通过网络发送数据。
  • 另外,我可以在 SQLPlus 中运行这些查询,但是它似乎没有报告查询和获取需要多长时间。是否有启用此功能的选项?
  • 糟糕 - 找到它:设置时间;
  • SQLPlus 中的时间似乎很相似。返回所有行大约需要 44 秒,并且 SELECT COUNT() 几乎相同。我会弄乱 FETCH 大小,看看是否有区别。
  • 有趣的是,如果我将数组大小设置为 1,000,那么查询将从 44 秒变为 3 秒。现在我只需要弄清楚如何在 .NET 中执行此操作,呵呵。我认为将其设置得太高会有一些缺点,尤其是对于不可靠的连接。
【解决方案2】:

在处理网络应用程序时,快速获取某些内容很重要。 调查 FIRST_ROWS 提示。这可能对您的情况有价值。

【讨论】:

    【解决方案3】:

    从表中选择几千行应该不会花费将近一分钟。我的猜测是您系统的其他地方存在性能问题。可能是数据库中的其他活动,或服务器/网络/存储问题。数据库中其他查询的性能是否同样缓慢?

    【讨论】:

      【解决方案4】:

      请检查表碎片。通常 Table Fragmentaion 会导致更多的 I/O 和查询变慢。您可以使用 oracle 段顾问来检查它并解决它有两种方法首先使用 oracle 收缩表命令:是减慢并锁定表,第二种使用 oracle move table 命令,如果使用 oracle 并行选项,这个特别快.关于移动表的唯一一点是它会使用未使用的索引。

      【讨论】:

        猜你喜欢
        • 2020-07-15
        • 2016-01-26
        • 2019-06-01
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多