1

我发现在 Progress 10.1 中,当查询中使用多个索引时,数据库将使用索引列表中的第一个索引,而不是最佳索引,也不是两个索引的子集。

有没有其他人经历过这个?

==================================================== ================

定义了几个索引,但我们正在查看的两个是: XIE1cac_role_person owning_entity_mnemonic owning_entity_key role_key

XIE2cac_role_person contract_obj person_role_code effective_from_date

最初我的代码如下,它使用第一个索引返回更大的数据集。:

FOR EACH cac_role_person NO-LOCK 
        WHERE cac_role_person.contract_obj = cbm_contract.contract_obj 
          AND cac_role_person.owning_entity_mnemonic = "BROKER"
          AND (
              (cac_role_person.effective_to_date > TODAY 
          AND  cac_role_person.effective_to_date >=  
               cbm_contract_component.contract_component_start_date)
           OR (cac_role_person.effective_to_date = ? 
          AND cac_role_person.effective_from_date <=                  
              cbm_contract_component.contract_component_start_date)
              ):

所以我现在强制它使用第二个索引:

FOR EACH cac_role_person NO-LOCK USE-INDEX XIE2cac_role_person
        WHERE cac_role_person.contract_obj = cbm_contract.contract_obj 
          AND cac_role_person.owning_entity_mnemonic = "BROKER"
          AND (
              (cac_role_person.effective_to_date > TODAY 
          AND  cac_role_person.effective_to_date >=  
               cbm_contract_component.contract_component_start_date)
           OR (cac_role_person.effective_to_date = ? 
          AND cac_role_person.effective_from_date <=                  
              cbm_contract_component.contract_component_start_date)
              ):

第一个代码在 30 小时内修复了大约 4 000 个,改进后在 12 小时内修复了 70 000 个。(循环是更大部分的一部分,但这只是我需要加快处理 17 倍的更改

4

1 回答 1

5

在某些情况下,程序员可以做出比编译器更好的索引选择。但这通常很少见。

在不知道所有实际索引定义(您没有提供)的情况下,不可能完全评估编译器可以选择哪些索引。鉴于您共享的内容,选择遵循规则(见下文),但规则与您上面描述的不同。

如果没有关于数据分布的数据,就真的不可能说所选择的索引是“最好的”还是最优的。尽管已经说过,具有诸如“BROKER”之类的值的字段似乎没有称为“contract_obj”的字段那么精细。但这只是一个猜测。

Progress 4GL 引擎可以使用多个索引来解析查询,但这并不意味着它会这样做,也不意味着如果这样做,它一定会得到更好的结果。要知道它是否这样做,您需要使用 XREF 进行编译并查看结果。

4GL 引擎使用静态的、编译时的索引选择。您可以在此处找到有关规则的一些非常详细的信息:http: //pugchallenge.org/downloads/352_Pick_an_Index_2013.pdf

最重要的规则是:最大化领先组件上相等匹配的深度。您有两个可能的相等匹配:

cac_role_person.contract_obj = cbm_contract.contract_obj 
cac_role_person.owning_entity_mnemonic = "BROKER"

因此,您的“最佳”索引(对数据分布一无所知)几乎肯定是以这两个字段为主要组成部分的索引。理想情况下,您的第三个组件是 cac_role_person.effective_to_date 字段。如果您没有任何符合该标准的索引,您可能需要考虑添加一个。

您显示的两个索引每个都有一个与前导组件的相等匹配。所以他们的实力是一样的。决胜局标准然后开始发挥作用——如果其中一个被指定为“主要”指标,它就会获胜。否则,由于未指示 BY 标准,因此按字母顺序获胜。

如果您缺少适当的索引或者您正在故意进行表扫描,那么指定最小索引通常是最快的。您可以通过查看以下输出来确定:

proutil dbName -C dbanalys > dbName.dba

具有最少块数的索引是您想要的索引。如果它们的大小大致相同,则选择最高的“利用率”。

FWIW——SQL 引擎使用基于成本的优化器。但是,如果您希望它正常工作,您必须定期更新统计信息。(而且它对您的 4GL 查询没有帮助。)(4GL 中可用的 SQL 语法是嵌入式 SQL-89,它不知道基于成本的优化器——这也无济于事。尝试在内部使用 SQL 4GL 会议是通往无尽挫折之路——不要去那里。)

于 2013-07-09T13:40:17.480 回答