我们有一个基于.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是过程名称。对于程序的每个数据库调用,我们都调用此查询。
此查询有什么问题吗?
您有能力修改正在生成的查询吗?似乎它正在对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
会更有效率。
您是否收集了词典统计信息?通常,很难对数据字典视图进行查询,因为您不能添加索引或其他结构来加快处理速度。但是至少收集字典统计信息可以为优化器提供更好的信息,以便能够选择更好的计划。
最后,是否可以在实例化视图中实例化数据字典中的数据,该视图会定期刷新以建立索引?这意味着结果不会立即反映出对程序定义的更改。另一方面,您通常不希望实时更改过程定义,并且总是可以在进行模式更改后刷新实例化视图。
删除在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
您应该真正考虑使用Oracle Enterprise Manager监视数据库。这是一个相当用户友好的Web应用程序,它将为您配置所有查询并快速告诉您运行缓慢的原因。有关详细信息,请参见Oracle网站。
我一开始没有看到查询有问题的任何内容,但这实际上取决于您的表结构,索引以及其他一些负载,以及在减速时遇到的并发问题。
通常,通过查看查询本身很难解决数据库性能问题。
这里是您需要遵循的一些简单步骤来诊断问题
explain plan
,这将告诉您查询的速度很慢]explain plan
上有索引吗?尝试一下。我已经故意放弃了UPPER调用,因为如前所述,这将导致不使用索引。
UPPER(object_name)