我是使用Oracle数据库的Web应用程序的开发人员。但是,UI通常会触发需要一段时间才能处理的数据库操作。因此,当这些情况发生时,客户端会想要一个进度条。
我最近发现我可以从第二个连接查询V $ SESSION_LONGOPS,这很好,但它只适用于花费超过6秒的操作。这意味着我无法更新UI中的进度条,直到6秒过去。
我已经对V $ SESSION中的等待时间进行了研究,但据我所见,这不包括等待查询。
有没有办法获得当前正在运行的会话查询的进度?或者我应该隐藏进度条直到6秒过去?
答案 0 :(得分:9)
这些操作是Pl / SQL调用还是只是长时间运行的SQL?
通过PL / SQL操作,我们可以在SET_SESSION_LONGOPS()
包中使用DBMS_APPLICATION_INFO
编写消息。我们可以在V$SESSION_LONGOPS
中监控这些消息。 Find out more。
为此,您需要能够以工作单位量化操作。这些必须是具体的迭代,数字而不是时间。因此,如果操作是插入10000行,则可以将其拆分为10个批次。 totalwork
参数是批次数(即10
),并且每1000行调用一次SET_SESSION_LONGOPS()以递增sofar
参数。这将允许您渲染10个温度计的温度计。
这些消息是基于会话的,但是没有自动的方法来区分当前消息与来自同一会话的先前消息。 SID。但是,如果为context
参数指定UID,则可以使用该值过滤视图。
这对于单个长时间运行的查询不起作用,因为我们无法将其划分为块。
答案 1 :(得分:2)
我发现这非常有用
dbms_session.set_module("MY Program" , "Kicking off ... ")
..
dbms_session.set_action("Extracting data ... ")
..
dbms_session.set_action("Transforming data ... ")
..
您可以使用
监控进度select module , action from v$session where sid = :yoursessionid
答案 2 :(得分:1)
多年来我用Oracle
进行了大量的网络开发,发现大多数用户更喜欢不确定的进度条,而不是一个不准确的确定条(几乎任何{{1}进度条让我烦恼不已),遗憾的是没有正确的方法可以准确地确定查询进度。
虽然您对长操作能力的研究是令人钦佩的,并且肯定有助于使数据库查询的进度更可靠,但它无法考虑可能/将影响Web操作的事务进度的无数其他变量(网络负载,数据库负载,应用服务器负载,客户端数据解析,用户点击提交按钮1000次等)。
我坚持使用Javascript回调的不确定进度方法。它实施起来要容易得多,它会根据需要管理用户的期望。
答案 3 :(得分:1)
使用V $ _SESSION_LONGOPS需要设置TIMED_STATISTICS = true或SQL_TRACE = true。必须为您的数据库模式授予ALTER SESSION系统特权才能执行此操作。
我曾尝试将V $ _SESSION_LONGOPS用于复杂且经常运行的查询。但事实证明,V $ _SESSION_LONGOPS可能会显示查询的部分的进度,如全表扫描,连接操作等。
另请参阅:http://www.dba-oracle.com/t_v_dollar_session_longops.htm
您可以做的只是向用户显示“查询仍在运行”。我实现了嵌套到<DIV>
中的<TD>
,它会随着浏览器发送的每个状态请求而变得更长。状态请求由window.SetTimeout
(每3秒)启动,并且是对服务器端过程的AJAX调用。服务器端程序返回的状态报告只是说“我们仍在运行”。进度条的宽度(即<DIV>
的宽度)每次增加<TD>
宽度的5%,并在显示100%后重置为5%。
对于长时间运行的查询,您可以跟踪它们在单独的表中所花费的时间,可能还有用于改变where子句的单个条目。您可以使用它来显示平均时间加上客户端对话框中刚刚过去的时间。
如果您在服务器端执行了长时间运行的PL / SQL过程等,请执行以下步骤: