2012-11-20 57 views
1

我有两种扫描大型全局数组中键级的方法,并试图找出一种方法是否比另一种更有效。

这是供应商提供的IntersystemsCaché数据库平台上的应用程序和数据库。它是用旧的MUMPS风格编写的,并没有使用任何Caché的对象持久化函数:所有数据直接存储在全局变量中,并且任何索引都是应用程序维护的。

重复附加到实体的数据元素有一个公共约定,其中第一条记录包含子记录计数,然后在下一个关键级别按顺序编号每个子记录。例如:

^GBDATA(12345,100)="3" 
^GBDATA(12345,100,1)="A^Record" 
^GBDATA(12345,100,2)="B^Record" 
^GBDATA(12345,100,3)="C^Record" 

其中“12345”是实体键,“100”是附加的详细类型之一。请注意,没有其他键的第一个“100”记录具有子记录数。可能有附加的0到数百个子记录之间的任何地方。这些实体通常很宽,除了这种子记录类型之外还有很多其他数据(示例中未显示)。

给定一个实体键,我想扫描一种类型的所有子记录。使用$ ORDER来遍历子项或使用FOR循环来预测关键值会更快吗?有关系吗?

$订购方法:

SET EKEY=12345 
SET SEQ="" 

FOR 
{ 
SET SEQ=$ORDER(^GBDATA(EKEY,100,SEQ), 1, ROWDATA) 
QUIT:SEQ="" 

WRITE ROWDATA,! 
} 

FOR计数方法:

SET EKEY=12345 
SET LIM=^GBDATA(EKEY,100) 

FOR SEQ=1:1:LIM 
{ 
WRITE ^GBDATA(EKEY,100,SEQ),! 
} 

有谁知道如何$ ORDER VS $ GET在高速缓存内部实现的?

由于我们只有一个生产实例具有适当的数据,并且无法使其脱机以清除缓存,所以我无法通过实验进行测试。我最喜欢磁盘性能而非缓存性能。

+1

如果约定永远不遵守,并且在索引中的差距,或限制值低于列表中的项目数,您的应用程序应该做什么?这比速度更重要吗?此外,您可以非常轻松地使用生产系统中的假数据进行测试。 – psr

+0

@psr - 过去,这种应用程序对这种约定一直非常一致,但我可能会使用$ GET和默认值来对冲缺少的值。我一直在使用$ ORDER,因为它总是有效,似乎是一个更直接的解决方案。我可以通过设置一个测试Caché实例来测试它,但是询问SO更容易,我想知道是否有人知道实现细节。 –

回答

1

您可以使用%SYS.MONLBL找出最终结果。我的猜测是$ ORDER稍好一些。

http://docs.intersystems.com/cache20122/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_monlbl

+0

另外,psr是正确的。 $ ORDER是一个更强大的解决方案和更好的实践。 – mcbainpc

+0

这是否给你比这个$ ZTIMESTAMP之前和之后的情况更有帮助?如果是这样的话,在你的回答中专门调出它会很好。我想对时间更精确一点是有用的。 – psr

+0

%SYS.MONLIBL报告的时间是否会受到正在访问的数据是否在数据缓存中的影响? –

0

在问候你的问题, “有谁知道如何$ ORDER VS $ GET在高速缓存内部实现的?”这两个是完全不同的功能。 $订单用于查看您的^ Global时要进入的方向。 $ Get用于在^ Global中提取数据。下面是它的一个例子。我使用Cache ObjectScript;然而,这应该给你一个总体思路

全球结构

^People(LastName,FirstName)="Phone" 

全球数据

^People(Doe,John)="10350" 
^People(Smith,Jane)="7405241305" 
^People(Wood,Edgar)="7555127598" 

代码示例

SET LASTNAME=0 
FOR QUIT:LASTNAME?." " DO 
.SET LASTNAME=$ORDER(^People(LASTNAME)) QUIT:LASTNAME?." " 
.SET FIRSTNAME=0 
.FOR QUIT:FIRSTNAME?." " DO 
..SET FIRSTNAME=$ORDER(^People(LASTNAME,FIRSTNAME)) QUIT:FIRSTNAME?." " 
..SET PHONE=$GET(^People(LASTNAME,FIRSTNAME)) 

在上面提供的示例中,它将从^ People全局中的第一条记录开始,然后使用$ Order从名字中的第一条记录开始。然后它将$获取^ People(LASTNAME,FIRSTNAME)节点的数据,这是电话号码。

对于一些样品和参考区域,请查看以下链接:

$Get Information

$Order Information

+0

这很棒,但我知道这些功能的作用以及如何在问题中阅读我的代码示例时如何使用它们。问题是关于比较效率,而不是用法。 PS,我看到你喜欢旧的DO和点符号块。 –