Indexing 转换为本机oracle Sql的Open Sql Sql通过where子句选择任意索引?

Indexing 转换为本机oracle Sql的Open Sql Sql通过where子句选择任意索引?,indexing,oracle-sqldeveloper,where-clause,abap,Indexing,Oracle Sqldeveloper,Where Clause,Abap,我们在一个客户项目中发现了一个奇怪的行为。底层数据库是oracle,所以这个问题被标记为oracle,因为我们只在开放sql层操作,这使得我们对底层数据库体系结构/流程/优化的了解等于零 让我如实描述一下设计: 我们有两个表,一个是核心表,另一个是 可选附加表 始终填充核心表,而不填充其他表 core表有键MANDT、WERKS和我们自己的running ID 可选表具有相同的键,这些键设置为一组 外置键,参考核心表 外键设置为:需要控制,无消息,外键类型为“未指定”,未设置基数 现在让我具体说

我们在一个客户项目中发现了一个奇怪的行为。底层数据库是oracle,所以这个问题被标记为oracle,因为我们只在开放sql层操作,这使得我们对底层数据库体系结构/流程/优化的了解等于零

让我如实描述一下设计:

  • 我们有两个表,一个是核心表,另一个是 可选附加表
  • 始终填充核心表,而不填充其他表
  • core表有键MANDT、WERKS和我们自己的running ID
  • 可选表具有相同的键,这些键设置为一组 外置键,参考核心表
  • 外键设置为:需要控制,无消息,外键类型为“未指定”,未设置基数
  • 现在让我具体说明一下我们要做什么:

  • 我们有自己的查询生成器,它允许我们几乎通过拖放技术创建select语句
  • 我们希望根据三个键域(实际上是两个键域),选择具有可选表内部联接的核心表(是的,在这种特定情况下,主数据告诉我们,此可选表也总是填充的)
  • 我们在两个表上都有一些索引,在核心中我们使用索引ERDAT(创建日期),在可选表中我们使用一个char20字段,也被索引
  • 我们想这样选择
  • 我们调试
  • 让我描述一下,我们看到了什么:

  • 我们在调试器中分析了创建的select语句,并验证了 正如我们所希望的那样,这意味着where子句首先覆盖了核心表中的ERDAT,第二行覆盖了可选表的char20字段
  • 我们进行了运行时分析(为where标准提供其他值),运行ST05等。。。虽然底层数据库对我们来说是一个黑盒子,但显然ST05可以显示生成的本机SQL索引顺序,这是使用的
  • 结果:首先使用可选表的索引CHAR20,然后使用CORE表ERDAT上的索引
  • 让我问一下:

  • 谁能解释一下,为什么?(如果需要更多信息,我会尽力提供)

  • Oracle通常使用基于成本的优化器来执行查询。根据索引的选择性和连接的最佳执行方式,DB决定首先查询哪个表

    我只能猜测,但我认为您的核心表有很多值,并且该表上的索引不是很有选择性。因此,首先查询核心表可能会产生许多结果行。 如果可选表只有很少的行,则在使用CHAR20字段上的索引进行查询时,预计它将提供更少的行。在这种情况下,DB将以较小的结果集开始连接,因此更喜欢此选项

    查询优化是一个非常复杂的过程,您可以在此处了解更多信息:

    在本例中,主数据要求进行处理,即每当填充核心表时,可选表也将被填充,因此两个表中的记录量始终相同。但是,我能想象的是(我还没有读到链接),一个字符为20的字段和一个只有8位的日期字段(甚至更限于天/月)比日期更有可能携带唯一值。可能是,db以这样的方式进行优化,在这种情况下,我们可以使用提示来强制使用自己的索引顺序吗?是的,您可以在OpenSQL中使用提示。请参阅SAP说明129385(开放式SQL中的数据库提示):