重写 Oracle SQL 查询

Posted

技术标签:

【中文标题】重写 Oracle SQL 查询【英文标题】:Rewrite the Oracle SQL Query 【发布时间】:2020-04-12 03:23:18 【问题描述】:

我正在使用 Oracle DB 并编写了一个带有自连接的查询来获取一些数据。表很大,查询运行时间长,没有加索引的余地。记录的值在 SELECT 和 WHERE 条件下。有人建议我通过从 WHERE 条件中删除值来修改查询,从而产生相同的输出。有人可以分享你的想法吗?

select a.xid, a.sIdentifier
from    tbllarge a
        inner join tbllarge b on a.xid = b.xid
where   a.sIdentifier ='A1'

【问题讨论】:

管理员不允许修改架构,在我执行查询的环境中 JOIN 的意义何在? XIDTBLLARGE 上的主键还是唯一键? @BobJarvis-ReinstateMonica 。是的,XID 是主键 @Nick 例如,我们需要有关员工及其经理的详细信息,其中员工 ID 和经理 ID 位于同一个表中。 【参考方案1】:

将查询重写为

SELECT XID, SIDENTIFIER
  FROM TBLLARGE
  WHERE SIDENTIFIER = 'A1'

XID 是表上的主键,因此自连接只是将行连接到自己,这并没有真正做任何重要的事情。跳过自联接,您的查询会运行得更快,尽管在 SIDENTIFIER 上没有索引我怀疑它会运行得特别快。

【讨论】:

如果XID是主键,那么Oracle应该可以eliminate this unnecessary self-join【参考方案2】:

这似乎是一个奇怪的查询:

select a.xid, a.sIdentifier
from tbllarge a join
     tbllarge b
     on a.xid = b.xid
where a.sIdentifier = 'A1'

我将其解释为:

select a.*
from tbllarge a
where a.sIdentifier = 'A1' and
      exists (select 1 from tbllarge b where a.xid = b.xid);

对于任一查询,您都需要两个索引:(sIdentifier, xid)(xid)。如果xid 是主键,那么该索引已经存在。

【讨论】:

以上是关于重写 Oracle SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server索引视图以(物化视图)及索引视图与查询重写

如何用 Oracle 的符号 (+) 重写查询

Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数

为了比较,在没有 IN 条件的情况下重写 Oracle 查询/更新

SQL 帮助 - 重写查询

如何重写具有连接子查询的 SQL 查询