Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 使用进程的索引中带不等式的查询_Performance_Indexing_Progress 4gl_Openedge - Fatal编程技术网

Performance 使用进程的索引中带不等式的查询

Performance 使用进程的索引中带不等式的查询,performance,indexing,progress-4gl,openedge,Performance,Indexing,Progress 4gl,Openedge,使用4GL查询记录的最快方法是什么?例如,如果我需要查找其状态字段与'MI'不匹配的所有记录,我将如何编写这些记录以获得最佳性能?为什么 我被告知的各种解决方案包括使用更广泛或不同的索引,然后使用IF语句,以避免使用不平等性,例如: FOR EACH record NO-LOCK: IF record.state = "MI" THEN NEXT. /*do stuff*/ END. 我被告知避免使用NE语句,因为它们会破坏性能 FOR EACH record NO-LOCK WH

使用4GL查询记录的最快方法是什么?例如,如果我需要查找其状态字段与'MI'不匹配的所有记录,我将如何编写这些记录以获得最佳性能?为什么

我被告知的各种解决方案包括使用更广泛或不同的索引,然后使用IF语句,以避免使用不平等性,例如:

FOR EACH record NO-LOCK:
  IF record.state = "MI" THEN NEXT.
  /*do stuff*/
END.
我被告知避免使用NE语句,因为它们会破坏性能

FOR EACH record NO-LOCK
  WHERE record.state NE "MI":
  /*do stuff slowly, apparently*/
END.
但我也被告知使用OR也是邪恶的

FOR EACH record NO-LOCK
  WHERE record.state = "WI" OR "AL":
  /*didn't write all 49 minus MI for space*/
END.

我还没有得到实质性的证据来证明这三种方法中的任何一种都是优越的,而且我的开发环境中也没有足够的数据来测试我正在处理的实际情况。

这一切都取决于您的查询与可用索引的匹配程度

您的第一个示例执行所谓的表扫描—在执行IF之前,它将查看表中的每一条记录,以确定它是否是您想要的记录。大多数情况下,这不是您想要的,尤其是当表很大或经常查询时

equals=是性能最好的,尤其是当您查询的一个或多个字段上有索引时

或者,如果它与一个和相结合,则可能是邪恶的:

WHERE customer.AmountDue > SomeValue AND 
      (customer.state = "MI" OR customer.state = "WI").
原因是db引擎无法使用ORs执行任何索引查找,因此它将解析>运算符,然后检查与>匹配的每个记录,以查看它是否匹配这两种状态中的任何一种

这可以通过重构来解决,如下所示:

WHERE (customer.AmountDue > SomeValue AND customer.state = "MI") OR 
      (customer.AmountDue > SomeValue AND customer.state = "WI").
使用这种结构,db引擎有两个短语,它可以解析为一组较小的结果,将两个列表合并在一起,最终结果是查询要遍历的一组记录。这比在问题的第一部分使用OR要快得多

所有这一切都归结为与您正在查询的表上的索引匹配的查询。如果有一个索引与您要查找的内容完全匹配,那么它将比有一个部分匹配您的查询的索引或根本没有匹配的索引快得多

您需要做的是查看在不同的帕格挑战大会上所做的一些出色的演示。您可以在这里找到帕格美洲挑战赛上关于索引选择的演示:

您可以在的“先前活动”选项卡中找到帕格挑战EMEA的演示文稿


祝你好运

这完全取决于您真正想做什么,以及实际的数据和索引是什么

幸运的是,您可以使用类似于以下内容的线束来测试这些东西:

define variable i  as integer no-undo.
define variable lr as integer no-undo.

find _myconnection no-lock.

find _userio no-lock where _userio-id = _myconn-userid + 1.

lr = _userio-dbaccess.

for each metric-desc no-lock              /* query to test goes here... */
    where db-id < 1600 or db-id > 1600:

  i = i + 1.

end.

find _userio no-lock where _userio-id = _myconn-userid + 1.
lr = _userio-dbaccess - lr.

display lr i.
在本例中,我有一个名为metric-desc的表。它碰巧有一个索引,其前导组件是一个名为db-id的字段。有点像有一个名为state的字段

它有13358条记录

有52条记录的db id=1600,我从稀薄的空气中提取了1600条,很像state=MI

如果我注释掉WHERE子句并读取整个内容,我会得到26994个逻辑读取索引项和记录,这就是db引擎解析查询所做的工作

如果我使用类似于示例中状态“MI”的db id 1600,我会得到相同的结果-扫描整个表

如果我用显示的OR替换where子句,则需要26892次逻辑读取-不读取db id=1600的记录

就一般的经验法则而言,=是你的朋友,通常是坏的还是坏的。如果你能想出一种表达某事的方式,那将是最有效的。Range matches=不太好,但它们不如或可能是好的-这取决于索引和如何组合查询


最重要的索引规则是在前导组件上使用尽可能多的相等匹配。一旦你偏离了这条规则,你就是在做出妥协。

Tim,你关于“平等=和不平等同等表现”的评论应该重新考虑。虽然两者都很有帮助,但我选择了这个答案,因为我从未考虑过做类似于你展示的第二个where子句的事情。此外,帕格网站的链接也是不错的来源。感谢你们两位@TomBascom