如果我不在我的程序中使用索引字段怎么办?

问题描述

我是这个进步 4GL 的初学者。我对以下逻辑感到困惑,尤其是索引的实际工作方式。

我在一个索引中添加了 2 个字段。如下所示,我编写了三个查询

查询1,使用索引并从2个字段中查找数据来检索数据

查询 2,使用相同的索引但仅从 1 个字段中查找数据

查询3,使用同一个索引字段和一个非索引字段

define temp-table tt_creldata no-undo
field tt_cscx_order    as character 
field tt_cscx_part     as character
field tt_cscx_shipfrom as character
index tt_cscx
      tt_cscx_order
      tt_cscx_part
.
**Query 1:**
find first tt_creldata use-index tt_cscx 
      where tt_cscx_order = "153" 
      and tt_cscx_part = "113" no-lock no-error.

**Query 2:**
find first tt_creldata use-index tt_cscx 
       where tt_cscx_order = "153" no-lock no-error.

**Query 3:**
find first tt_creldata use-index tt_cscx
      where tt_cscx_order = "153" 
      and tt_cscx_part = "113" 
      and tt_cscx_shipfrom = "US" no-lock no-error.

问题 1:哪个查询有助于提高性能

问题 2:如果我不使用一个在我提到 use-index 时被索引的字段会怎样

问题 3:如果我在提到 use-index 时添加一个非索引字段怎么办?

解决方法

作为一般经验法则,您永远不应使用 use-index

AVM 将在编译时选择一个或多个索引用于查询,并通过强制它使用您选择的一个索引来消除这种可能性。

如果您让 AVM 选择(即不使用 use-index ),在您的 where 子句中有额外的,可能是非索引的字段只会影响选择的索引。如果您不在查询中使用索引字段,情况也是如此。

如果您使用 xrefxml-xref 选项编译程序并查找 SEARCH 项,您可以看到使用了哪些索引。

,

正如 nwahmaet 所说,你永远不应该使用 USE-INDEX。在这种情况下,它特别没有意义,因为只有一个索引。在有多个索引的情况下,无论 WHERE 子句多么复杂,FIND 语句都只会使用其中一个,但编译器几乎总是比您选择一个有效的索引做得更好。 (FOR EACH 语句及其关联的动态查询能够使用多个索引。FIND 总是仅限于一个索引。)在那些您认为自己做得更好的极少数情况下,您应该彻底记录为什么您的选择更好并且包括详细的测试用例和结果。

您的所有查询都使用 FIRST。这是必要的,因为您的索引未定义为唯一的。这可能是您的意图,但这似乎不寻常。这意味着如果出现具有相同键值的重复记录,您会神奇地使“第一个”记录比其他记录更特别。这是数据规范化的失礼(您将“第一性”作为数据的属性)和等待发生的错误。

FIND FIRST 和 USE-INDEX 经常一起使用来(试图)掩盖彼此的不足。通过指定特定索引,FIRST 变得更加一致。同样,FIRST 通常用于“解决”由于索引定义不足、WHERE 子句不足或在 FOR EACH 更合适时选择 FIND 而引起的性能问题。

这些查询的执行速度都不会比其他查询快得多。

查询 2 可能会或可能不会返回与查询 1 相同的记录。例如,如果有一部分 = "112",则查询 2 将具有不同的“第一”记录。但是返回的速度和查询 1 一样快。

同样,查询 3 可能有不同的结果,具体取决于哪些记录包含 shipfrom = "US"。在第一个命令 = "153" 和部分 "113" 也满足 shipfrom = "US" 的最佳情况下,它将与其他命令具有相同的速度。

但是,查询 3 可能 会慢很多,这取决于在找到具有 shipfrom = "US" 的记录之前必须扫描多少记录,因为该字段是不是任何索引的一部分并且匹配它,因此,需要扫描记录,直到找到匹配的记录。这可能是第一条记录,也可能是第 10 条记录。