Oracle Select Query占用太长时间

时间:2011-10-04 17:07:41

标签: .net sql oracle oracle10g

我们有一个基于.Net的内部应用程序,它调用Oracle中的某些程序(10g)。运行这些查询之一以获取这些过程的参数。这是一个非常简单的选择查询。但即使在最好的情况下,它也需要3秒钟。每天至少几次,它开始花费超过40秒,并导致我们的.Net应用程序超时。选择查询是:

SELECT   a.argument_name,
           a.data_type,
           a.in_out,
           NVL (a.data_length, 0) AS data_length,
           NVL (a.data_precision, 0) AS data_precision,
           NVL (a.data_scale, 0) AS data_scale
    FROM   ALL_ARGUMENTS a, all_objects o
   WHERE   o.object_id =
              (SELECT   object_id
                 FROM   all_objects
                WHERE       UPPER (object_name) = UPPER ('resourcemanager_pkg')
                        AND object_type = 'PACKAGE'
                        AND owner = 'OFFICEDBA')
           AND UPPER (a.object_name) = UPPER ('p_search_roles')
           AND a.OBJECT_ID = o.OBJECT_ID
ORDER BY   a.position ASC

此查询返回特定过程的输入/输出参数。

resourcemanager_pkg是包名,p_search_roles是过程名。 我们为每个数据库调用程序调用此查询。

这个查询有什么问题吗?任何帮助将不胜感激。如果需要任何其他信息,请与我们联系。

谢谢, Vikalp Jain

5 个答案:

答案 0 :(得分:3)

删除oracle视图上对UPPER()的所有调用。它们已经是大写的。我还将包名称查询移动到'with子句',因此它被调用一次。

WITH PACKAGE AS
     (SELECT object_id, owner, object_name NAME
        FROM all_objects
       WHERE object_name = UPPER ('SOME_PACKAGE_NAME')
         AND object_type = 'PACKAGE'
         AND owner = 'SOME_SCHEMA_OWNER_NAME')
SELECT   a.argument_name, a.data_type, a.in_out,
         NVL (a.data_length, 0) AS data_length,
         NVL (a.data_precision, 0) AS data_precision,
         NVL (a.data_scale, 0) AS data_scale
    FROM ALL_ARGUMENTS a, PACKAGE
   WHERE a.package_name = PACKAGE.NAME AND a.owner = PACKAGE.owner
   --This is the 'procedure' name within the package.
   AND a.OBJECT_NAME = 'SOME_PROCEDURE_NAME'
ORDER BY a.POSITION ASC

答案 1 :(得分:2)

您是否能够修改正在生成的查询?它似乎正在对ALL_OBJECTS表进行无关联。您的查询似乎等同于此

SELECT   a.argument_name,
           a.data_type,
           a.in_out,
           NVL (a.data_length, 0) AS data_length,
           NVL (a.data_precision, 0) AS data_precision,
           NVL (a.data_scale, 0) AS data_scale
    FROM   ALL_ARGUMENTS a,
           (SELECT   object_id
              FROM   all_objects
             WHERE       UPPER (object_name) = UPPER ('resourcemanager_pkg')
                     AND object_type = 'PACKAGE'
                     AND owner = 'OFFICEDBA') o
    WHERE  UPPER (a.object_name) = UPPER ('p_search_roles')
      AND  a.OBJECT_ID = o.OBJECT_ID
    ORDER  BY a.position ASC

我还希望使用ALL_PROCEDURES而不是ALL_OBJECTS来获取OBJECT_ID会更有效率。

你收集了字典统计数据吗?对数据字典视图的查询通常很难调整,因为您无法添加索引或其他结构来加快速度。但至少收集字典统计信息可能会为优化程序提供更好的信息,以便能够选择更好的计划。

最后,您是否有可能在物化视图中实现数据字典中的数据,并定期刷新您可以编制索引?这意味着结果不会立即反映程序定义的变化。另一方面,您通常不希望实时更改过程定义,并且可以在进行模式更改后始终刷新实例化视图。

答案 2 :(得分:0)

您应该考虑使用Oracle Enterprise Manager监控数据库。它是一个合理的用户友好型网络应用程序,可以为您分析所有查询,并快速告诉您为什么运行缓慢。有关详细信息,请参见Oracle的网站。

我一开始没有看到任何错误的查询,但它实际上取决于你的表结构,索引以及你在减速时遇到的并发问题。

答案 3 :(得分:0)

通过查看查询本身,通常很难解决数据库性能问题。

以下是诊断问题时需要遵循的一些简单步骤

  • explain plan,这会告诉您查询的速度很慢
  • 检查索引,是否有UPPER(object_name)的索引?
  • 检查统计信息,是最新的吗?

答案 4 :(得分:0)

试一试。我故意忘记了UPPER调用,因为如前所述,这将导致不使用索引。

SELECT   a.argument_name,
       a.data_type,
       a.in_out,
       NVL (a.data_length, 0) AS data_length,
       NVL (a.data_precision, 0) AS data_precision,
       NVL (a.data_scale, 0) AS data_scale
from all_arguments a
    inner join all_objects o ON o.object_id = a.object_id
where o.object_name = 'resourcemanager_pkg'
    and o.object_type='PACKAGE'
    AND O.OWNER = 'OFFICEDBA'
    AND A.OBJECT_NAME='p_search_roles'
ORDER BY   a.position ASC