oracle 19c中取前10行最可靠方式是fetch first 10 rows only,必须搭配order by,语义清晰、性能可控;rownum

Oracle 19c 用 FETCH FIRST 取前10行最可靠
Oracle 19c 原生支持标准 SQL:2008 的分页语法,FETCH FIRST 是唯一推荐方式——它语义清晰、性能可控,且不依赖排序隐含行为。
常见错误是沿用旧版 ROWNUM 写法:它在未加 <code>ORDER BY 子句时结果不可预测;加了 ORDER BY 又容易写成子查询嵌套,导致全表扫描后再排序,效率低下。
正确写法示例:
SELECT employee_id, last_name, salary FROM employees ORDER BY salary DESC FETCH FIRST 10 ROWS ONLY;
-
FETCH FIRST 10 ROWS ONLY表示严格取前10行,WITH TIES可选(当第10名有并列时一并返回) - 必须搭配
ORDER BY,否则 Oracle 报错ORA-00936: missing expression - 如果只想要“任意10行”(无序),可用
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY,但业务上极少这么用
为什么不用 ROWNUM ?
ROWNUM 是 Oracle 伪列,在查询结果集生成过程中逐行赋值,不是排序后才编号。这意味着 WHERE ROWNUM 实际上是在排序前就截断了数据,结果完全随机。
想让它“看起来对”,有人会这样写:
SELECT * FROM ( SELECT * FROM employees ORDER BY salary DESC ) WHERE ROWNUM <p>但这种写法存在隐患:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4996" title="Crypto Sniper Oracle"><img src="https://img.php.cn/upload/skill/000/000/081/179031080953882.jpg" alt="Crypto Sniper Oracle" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill4996" title="Crypto Sniper Oracle" class="overflowclass">Crypto Sniper Oracle</a> <p class="overflowclass">机构级量化市场预言机,提供订单簿失衡(OBI)、VWAP分析、自动化报告及Telegram预警。</p> </div> <a rel="nofollow" href="/xiazai/skill4996" title="Crypto Sniper Oracle" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
- Oracle 优化器可能忽略外层
WHERE对内层排序的影响,尤其在复杂连接或函数列场景下 - 无法使用
FETCH FIRST自带的优化提示(如自动选择索引快速全扫描) - 语义模糊:读者需多读一层嵌套才能理解意图,维护成本高
FETCH FIRST 在分页场景下的注意事项
如果后续要实现“第2页(11–20行)”,不能简单改数字,必须配合 OFFSET:
SELECT employee_id, last_name, salary FROM employees ORDER BY salary DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
关键点:
-
OFFSET值从 0 开始,OFFSET 10表示跳过前10行 - 大偏移量(如
OFFSET 100000)性能会明显下降,因为 Oracle 仍需定位到第100001行——这不是游标式分页,而是逻辑偏移 - 若需高效深分页,应改用基于排序键的游标分页(例如记录上一页最大
salary,用WHERE salary + <code>FETCH FIRST 10 ROWS ONLY)
兼容性与执行计划差异
FETCH FIRST 在 Oracle 12c 及以后都可用,但 19c 对其优化更成熟:当 ORDER BY 列上有索引时,执行计划中常出现 WINDOW NOSORT STOPKEY,说明 Oracle 直接利用索引有序性提前终止扫描。
而 ROWNUM 方式即使有索引,也常显示 VIEW + SORT ORDER BY STOPKEY,多一层视图包装,且排序动作未必被完全消除。
验证方法:执行 EXPLAIN PLAN FOR ... 后查 PLAN_TABLE,重点关注 OPERATION 和 OPTIONS 列。
真正容易被忽略的是:FETCH FIRST 要求 ORDER BY 列必须可比较、非空(或明确处理 NULL),否则可能因 NULLS FIRST/LAST 设置不同导致结果波动。










