我发现在 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/