我们正在使用OpenEdge 10.2A,并使用进度过程生成摘要报告。我们希望减少报告的制作时间。
由于使用Accumulate和Accum函数实际上并不比定义变量来获取汇总值要快,并且它们的可读性差得多,因此我们并没有真正使用它们。
我们已经使用ODBC连接使用SQL命令测试了数据,结果比使用过程要快得多。
让我给你一个例子。我们运行以下过程:
DEFINE VARIABLE i AS INTEGER NO-UNDO.
ETIME(TRUE).
FOR EACH orderline FIELDS(ordernum) NO-LOCK:
ASSIGN i = i + 1.
END.
MESSAGE "Count = " (i - 1) SKIP "Time = " ETIME VIEW-AS ALERT-BOX.
结果是:
Count= 330805
Time= 1891
当我们运行等效的SQL查询时:
SELECT count(ordernum) from pub.orderline
执行时间为 141 。
简而言之,当我们比较两个结果时; sql时间比过程时间快13倍以上。
这只是一个例子。我们可以使用其他聚合函数进行相同的测试,并且时间比例变化不大。
我的问题分为两部分;
1-)是否可以使用与使用sql查询一样快的过程来获取聚合值?
2-)除了使用实时SQL查询之外,还有其他方法可以更快地获取汇总值吗?
答案 0 :(得分:4)
4gl和SQL引擎使用非常不同的方法来将数据发送到客户端。默认情况下,SQL要快得多。要从4gl获得类似的性能,您需要调整几个参数。我建议:
-Mm 32600 # messages size, default 1024, max 32600
-prefetchDelay # don't send the first record immediately, instead bundle it
-prefetchFactor 100 # try to fill message 100%
-prefetchNumRecs 10000 # if possible pack up to 10,000 records per message, default 16
在11.6更改之前-Mm需要同时更改客户端和服务器。从11.6开始,仅需要更改服务器。
-prefetch *参数至少需要OpenEdge 10.2b06。
尽管有一些注意事项(在其他方面,联接将无济于事),但这些参数可能会极大地提高“ NO-LOCK查询”的性能。一个简单的:
FOR EACH table NO-LOCK:
/* ... */
END.
使用上述参数可以大大改善。
使用FIELDS列表也有很大帮助,因为它减少了数据量,从而减少了需要发送的消息数量。因此,如果您只需要某些字段而不是整个记录,则可以编写如下代码:
FOR EACH customer FIELDS ( name balance ) NO-LOCK:
或:
FOR EACH customer EXCEPT ( photo ) NO-LOCK:
您已经在使用FIELDS,并且示例查询是一个简单的NO-LOCK,因此应该从建议的参数设置中受益匪浅。
答案 1 :(得分:1)
眼前的问题似乎是“减少了报告的制作时间。”
这引起了一些问题:
没有更多信息,将不可能回答您的问题。在以下情况下,来自ABL的数据访问将足够快:
像FOR EACH <table> NO-LOCK:
或SELECT COUNT(something) FROM <somewhere>
这样的简单命令所花费的时间可能并不表示您真正的超级复杂查询的运行速度有多快。
答案 2 :(得分:1)
一些其他建议:
可以将您的示例写为
DEFINE VARIABLE i AS INTEGER NO-UNDO.
ETIME(TRUE).
select count(*) into i from orderline.
MESSAGE "Count = " (i - 1) SKIP "Time = " ETIME VIEW-AS ALERT-BOX.
应该会产生适度的性能提升。 (这不是使用ODBC连接。您可以在简单的4GL过程中使用SQL的子集。如果可以认为这是好的样式,则值得商)。)
如果在服务器上运行代码(这样做)并且还没有这样做(没有这样做),则通过共享内存而不是TCP / IP访问数据库应该会显着提高性能。指定)。
答案 3 :(得分:0)
打开查询 q 预选每个订单线无锁定。 message num-results("q") view-as alert-box.