用作内联查询连接条件时,使 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;
我收到一个查询,其中我试图从另一个 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;