database - Progress RDBMS 索引问题 - 供引用

标签 database progress-4gl openedge progress-db

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

有没有其他人遇到过这种情况?

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

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

XIE2cac_role_person 契约(Contract)对象 人员角色代码 生效日期

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

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

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

FWIW -- SQL 引擎使用基于成本的优化器。但是,如果您希望它运行良好,则必须定期更新统计信息。 (而且它不会帮助您的 4GL 查询。)(4GL 中可用的 SQL 语法是嵌入式 SQL-89,它不知道基于成本的优化器——这也无济于事。尝试在4GL session 是通向无尽挫折的道路——不要去那里。)

关于database - Progress RDBMS 索引问题 - 供引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17543888/

相关文章:

csv - 最后导入的行为空 输入流进度

oop - 使用面向对象编程进行进度openge的利弊

database - 通过 JDBC 连接到 Talend 中的 OpenEdge

xml - 如何在 Progress 4GL 中发送 SOAP header

database - DB2 通信错误

database - GQL 中是否有 OR 运算符?

java - JDBC:与数据库无关

sql - 在 MS Access 中合并字段

progress-4gl - 我如何使用 FOR 每个,通过表格查看 OpenEdge 中升序的字段之一?

sql - 进度 dbtool 错误