我之前的问题:
Date of max id: sql/oracle optimization
在我之前的问题中,我找到了找到id值最高的记录日期的不同方法。以下是几个提供的解决方案,以及按解释计划计算的“成本”。
select date from table where id in (
select max(id) from table)
费用为8
select date from table where rownum < 2 order by id desc;
费用为5
select date from (select date from table order by id desc) where rownum < 2;
的成本也是5
with ranked_table as (select rownum as rn, date from table order by id desc)
select date from ranked_table where rn = 1;
的费用为906665
SELECT t1.date
FROM table t1
LEFT OUTER JOIN table t2
ON t1.id < t2.id
WHERE t2.id IS NULL;
的费用为1438619
显然,id的索引正在发挥作用。但我想知道,在最后两个表演的情况下,如果不是更好,最后两个表现如何?我想了解这样做的好处。
这是在Oracle中完成的。可以讨论所有品种,但请说明你的答案适用。
答案 0 :(得分:4)
如果您想要最适合各种其他品牌RDBMS的可移植SQL(即并非所有品牌都支持rownum
),请使用解决方案#1:
select date from table where id in (select max(id) from table);
如果您想要最有效的Oracle解决方案,请使用解决方案#3:
select date from (select date from table order by id desc) where rownum < 2;
请注意,解决方案#2并不总能给出正确的答案,因为它会在之前返回“第一个”两行,并按id
对它们进行排序。如果发生这种情况会返回具有最高id
值的行,那只是巧合。
select date from table where rownum < 2 order by id desc;
对于提供如此高成本的更复杂的查询#4和#5,我同意我不建议将它们用于获取具有最高id
的行这样的简单任务。但是理解如何使用子查询因子和自联接对于解决其他更复杂类型的查询非常有用,其中简单的解决方案根本无法完成工作。
示例:给定一个线程论坛评论的层次结构,显示最热门的评论与最直接的回复。
答案 1 :(得分:1)
几乎所有体面的数据库都引入了称为优化器提示的指令,这些指令不可移植,加入表时有默认成本,您可以建议查询优化器使用嵌套循环连接或动态表散列连接。对你在oracle performance tuning guide
中找到的oracle的一个很好的解释