Oracle - 为什么选择SELECT * FROM Foo;太慢了?

时间:2011-09-22 21:10:49

标签: sql database oracle networking oracle11g

我正在使用我们的网络应用程序解决一些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] 

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

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

是否有任何快速建议:a)确认网络带宽确实是问题; b)任何“陷阱”或要检查为什么通过线路序列化数据这么慢的事情?谢谢!

基于评论的一些更新:

  

SELECT COUNT(*)FROM(select * 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中选择PROJECTID;

结果:

  

选择了5825条记录[获取元数据:0ms] [获取数据:1m 0s]

     

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

表架构:

PROJECTID(NUMBER) WORKGROUPID(NUMBER)

4 个答案:

答案 0 :(得分:6)

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

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

Oracle可以选择配置SDU和TDU以及SQL * Net中的一些其他网络参数。但是,在你优化了提取大小并确保尽可能减少数据量之前,我不会开始考虑这些选项。

答案 1 :(得分:1)

当您正在处理网络应用时,快速获取内容非常重要。 调查FIRST_ROWS提示。这可能对你的情况有价值。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

请检查表格碎片。通常,Table Fragmentaion会导致更多的I / O和查询变慢。你可以使用oracle segment advisor来检查它并解决它有两种方法首先使用oracle shrink table命令:是慢速还是锁定表,第二次使用oracle move table命令,如果使用oracle parallel选项这个特别太快了。关于移动表的唯一一点是它将是未使用的索引。