【问题标题】:Progress RDBMS index issues - for information进度 RDBMS 索引问题 - 供参考
【发布时间】:2013-07-06 19:17:17
【问题描述】:

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

有其他人经历过吗?

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

定义了几个索引,但我们正在查看的两个是: XIE1cac_role_person 拥有实体助记符 拥有实体密钥 角色键

XIE2cac_role_person contract_obj person_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 倍的更改

【问题讨论】:

    标签: database progress-4gl openedge progress-db


    【解决方案1】:

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

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

    如果没有有关数据分布的数据,就无法确定所选索引是“最佳”还是“最佳”。尽管已经说过,具有诸如“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 会议是通往无尽挫折之路——不要去那里。)

    【讨论】:

    • ontract_obj 是 (FK) 但两个字段都不是 (PK)。数据是这样的,contract_obj 总是比 owning_entity_mnemonic 更有效。不幸的是,我们的 DBA 不相信对 DB 进行更改,因此我们必须解决它,至少这是一次性的数据修复。
    • Progress 不像 SQL 那样有 FK/PK 的概念,它会选择编译器认为合适的任何(一组)索引来完成它的工作。
    猜你喜欢
    • 2021-04-01
    • 2020-11-22
    • 1970-01-01
    • 2023-03-26
    • 2014-10-03
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多