RDBMS索引进度问题-供参考

Aqu*_*lex 1 database progress-4gl progress-db openedge

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

其他人有没有经历过?

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

定义了几个索引,但我们正在查看的两个索引是:XIE1cac_role_person ownering_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)
              ):
Run Code Online (Sandbox Code Playgroud)

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

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)
              ):
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*com 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"
Run Code Online (Sandbox Code Playgroud)

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

您显示的两个索引与前导组件具有单个相等匹配。因此它们具有同等的力量。决胜局标准随后发挥作用-如果其中一项被指定为“主要”指数,则该标准将获胜。否则,由于未指示BY标准,因此按字母顺序获胜。

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

proutil dbName -C dbanalys > dbName.dba
Run Code Online (Sandbox Code Playgroud)

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

FWIW-SQL引擎使用基于成本的优化器。但是,如果您希望统计数据运行良好,则必须定期更新统计数据。(而且它对您的4GL查询无济于事。)(4GL中可用的SQL语法是嵌入式SQL-89,它也不了解基于成本的优化器,也无济于事。 4GL会议是通往无尽沮丧的道路-不要去那里。)