进展RDBMS索引问题-供参考



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

有其他人经历过吗?

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

定义了几个索引,但我们正在研究的两个索引是:XIE1cac_role_personowning_entity_a助记符owning_entity_key角色密钥

XIE2cac_role_person合同_ objperson_role_code生效日期

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

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小时内完成了约4000个修复,改进后在12小时内修复了70000个。(循环是更大部分的一部分,但这只是我将处理速度提高17倍所需的更改

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

如果不知道所有实际的索引定义(您没有提供),就不可能完全评估编译器可以选择哪些索引。考虑到你分享的内容,选择遵循规则(见下文),但规则与你上面描述的不同。

如果没有关于数据分布的数据,就不可能判断所选索引是"最佳"还是最佳。尽管已经说过,像"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,它不知道基于成本的优化器,这也没有帮助。试图在4GL会话中使用SQL是通往无尽挫折的道路——不要去那里。)

相关内容

  • 没有找到相关文章

最新更新