Oracle select 查询花费的时间太长
我们有一个基于.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 是过程名称。 我们将此查询称为过程的每个数据库调用。
这个查询有什么问题吗?
We have an internal application based on .Net which calls certain procedures in Oracle (10g). One of these queries is run to get in/out parameters of these procedures. It's a pretty simple select query. But even under the best of circumstances, it is taking 3 seconds. At lease few times a day it starts taking more than 40 seconds and causes our .Net application to time out.
Select query is:
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
This query returns the in/out parameters of particular procedure.
resourcemanager_pkg is package name, p_search_roles is procedure name.
We call this query for every database call for procedures.
Is there anything which is wrong with this query?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
删除 oracle 视图上对 UPPER() 的所有调用。它们已经是大写的了。我还将包名称查询移至“with 子句”,以便调用一次。
Remove all the calls to UPPER() on the oracle views. They are in uppercase already. I've also moved the package name query to a 'with clause' so it is called once.
您是否能够修改正在生成的查询?它似乎正在对
ALL_OBJECTS
表进行无关的连接。看来您的查询与此相同,我还希望使用
ALL_PROCEDURES
而不是ALL_OBJECTS
来获取OBJECT_ID
会更有效。你收集过字典统计数据吗?针对数据字典视图的查询通常很难调整,因为您无法添加索引或其他结构来加快速度。但至少收集字典统计信息可以为优化器提供更好的信息,以便能够选择更好的计划。
最后,您是否可以将数据字典中的数据物化到定期刷新的物化视图中,以便您可以建立索引?这意味着结果不会立即反映程序定义的更改。另一方面,您通常不希望实时更改过程定义,并且您始终可以在进行架构更改后刷新物化视图。
Do you have the ability to modify the query that is being generated? It appears that it is doing an extraneous join to the
ALL_OBJECTS
table. It appears that your query is equivalent to thisI would also expect that using
ALL_PROCEDURES
rather thanALL_OBJECTS
to get theOBJECT_ID
would be more efficient.Have you gathered dictionary statistics? Queries against the data dictionary views are generally rather hard to tune since you can't add indexes or other structures to speed things up. But at least gathering dictionary statistics may give the optimizer better information to be able to pick a better plan.
Finally, is it possible that you could materialize the data from the data dictionary in a materialized view that refreshes periodically that you could index? That would mean that the results wouldn't immediately reflect changes to the definition of procedures. On the other hand, you don't generally want to be making changes to procedure definitions live and you can always refresh the materialized views after making schema changes.
您确实应该考虑使用 Oracle Enterprise Manager 来监视数据库。这是一个相当用户友好的网络应用程序,它将为您分析所有查询,并快速告诉您运行缓慢的原因。有关详细信息,请参阅 Oracle 网站。
我一开始没有看到查询有任何问题,但这实际上取决于您的表结构、索引以及在减速时遇到的其他负载、并发问题。
You should really consider monitoring your database with Oracle Enterprise Manager. It's a reasonably user-friendly web app that will profile all your queries for you and tell you quickly why your running slowly. See Oracle's web site for details.
I don't see anything at the start that's wrong with the query but it really depends on your table structure, indexes and what other loads, concurrency issues you've got going at the time of slowdown.
数据库性能问题通常很难通过查看查询本身来解决。
以下是诊断问题时需要遵循的一些简单步骤
解释计划
,这会告诉你查询速度慢的地方
UPPER(object_name)
上有索引吗?A database performance problem is generally hard to solve by looking at the query itself.
Here are some simple steps that you need to follow to diagnose the problem
explain plan
, this will tell you where your query is slowUPPER(object_name)
?试试这个。我故意保留了 UPPER 调用,因为如前所述,这将导致索引不被使用。
Try this out. I've left the UPPER calls out on purpose because as mentioned earlier, that will cause the Indexes not to be used.