我们有一个基于.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
答案 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