我写了一个查询,每个查询包含多个查询。查询花费了20多分钟来获取数据。有没有一种方法可以检查每个循环的开始和结束时间。 (每个循环执行需要花费多少时间,以及完成程序所花费的总时间)。
使用ETIME
,您可以启动毫秒计数器。可以调用一次或多次以告知自复位以来已过去了多少时间。
ETIME(TRUE).
/*
Loop is here but instead I'll insert a small pause.
*/
PAUSE 0.5.
MESSAGE "This took" ETIME "milliseconds" VIEW-AS ALERT-BOX.
毫秒在处理几分钟时可能没有用。然后,您可以使用TIME
来记录秒数,但是您需要自己处理开始时间。
DEFINE VARIABLE iStart AS INTEGER NO-UNDO.
iStart = TIME.
/*
Loop is here but instead I'll insert a slightly longer pause.
*/
PAUSE 2.
MESSAGE "This took" TIME - iStart "seconds" VIEW-AS ALERT-BOX.
如果要跟踪几次,最好将其输出到日志文件,而不要使用MESSAGE框,该框将在单击之前停止执行。
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE STREAM str.
OUTPUT STREAM str TO c:\temp\timing.txt.
ETIME(TRUE).
/*
Fake loop
*/
DO i = 1 TO 20:
PAUSE 0.1.
PUT STREAM str UNFORMATTED "Timing no " i " " ETIME "ms" SKIP.
END.
OUTPUT CLOSE.
您可以按照您的要求进行操作(只需遵循JensD的建议),但是最好使用Profiler。您可以轻松地为代码片段添加配置文件:
assign
profiler:enabled = yes
profiler:description = "description of this test"
profiler:profiling = yes
profiler:file-name = "filename.prf"
.
/* this is deliberately awful code that should take a long time to run */
for each orderline no-lock:
for each order no-lock:
for each customer no-lock:
if customer.custNum = order.custNum and orderLine.orderNum = orderLine.orderNum then
. /* do something */
end.
end.
end.
/* end of test snippet */
assign
profiler:enabled = no
profiler:profiling = no
.
profiler:write-data().
然后您可以将该prf文件加载到分析工具中。具体细节取决于您的开发环境-如果您使用的是PSDOE的最新版本,则包含一个Profiler分析器,如果没有,则可能要下载ProTophttps://demo.wss.com/download.php并使用lib / zprof_topx.p中包含的简单报告。
最终,您将发现,您的一个或多个FOR EACH语句几乎可以肯定使用了WHERE子句,该子句与可用索引的匹配度很低。
为了解决此问题,您需要确定实际选择了哪些索引并查看索引选择规则。有关该主题的一些优秀材料可以在这里找到:http://pugchallenge.org/downloads2019/303_FindingData.pdf
如果您不想麻烦阅读,那么至少应该看看实际的索引选择,如下所示:
compile program.p xref program.xref
所选索引是否符合您的期望?是否显示了WHOLE-INDEX(又名“表格扫描”)?