用作内联查询连接条件时,使 max() 函数更快

make max() function faster when used as inline query join condition

我收到一个查询,其中我试图从另一个 table 获取最大(日期)值以用作连接条件。

SELECT a.col1, a.col2 
  FROM tablea a, 
       tableb b
 WHERE a.pk_id = b.fk_id
   AND a.effdt = (SELECT MAX(effdt)
                    FROM tablea c
                   where c.id= a.id
                     and c.effdt <= sysdate
                  )

这里已经在 tablea 上为 effdt 列创建了一个索引,查询仍然需要很长时间才能获得 return 值。如果能更好地加入他们,那就太好了。

table c 上的子查询,effdt 上的索引不够。

(id, effdt) 上的索引会做得更好。关键是在单个索引中覆盖 where 子句和 max(effdt) 函数。这与索引 order by 非常相似:http://use-the-index-luke.com/de/sql/sortieren-gruppieren/indexed-order-by

除了按照 Markus 的建议添加 index 之外,试试这个。 IMO 连接比子查询工作得更好(对于我尝试过的场景)

SELECT a.*
FROM tablea a
INNER JOIN tableb b 
 ON a.pk_id = b.fk_id
INNER JOIN 
   (SELECT MAX(effdt) AS effdt
    FROM tablea
    WHERE effdt <= sysdate
    ) c ON c.id = a.id
    AND c.effdt = a.effdb

使用RANK()解析函数剔除相关子查询:

SELECT *
FROM   (
  SELECT a.*,
         RANK() OVER ( PARTITION BY a.id ORDER BY a.effdt DESC ) AS rnk
  FROM   tablea a
         INNER JOIN
         tableb b
         ON ( a.pk_id = b.fk_id )
  WHERE  a.effdt <= SYSDATE
)
WHERE  rnk = 1;