我在 Oracle 中有两个查询看起来非常相似,但执行时间却显示出显着差异。
-- Query 1: ROWNUM with ORDER BY
SELECT *
FROM coupang.PRODUCT as p
JOIN ( -- Subquery 1
SELECT id
FROM ( -- Subquery 2
SELECT id, ROWNUM AS rn
FROM coupang.PRODUCT
ORDER BY id
)
WHERE rn BETWEEN 5000000 AND 5000030
) AS t
ON p.id = t.id;
-- Query 2: ROWNUM without ORDER BY
SELECT *
FROM coupang.PRODUCT as p
JOIN ( -- Subquery 1
SELECT id
FROM ( -- Subquery 2
SELECT id, ROWNUM AS rn
FROM coupang.PRODUCT
)
WHERE rn BETWEEN 5000000 AND 5000030
) AS t
ON p.id = t.id;
两个查询都用于过滤行。ROWNUM 第一个查询包含子查询 2 中的子句,而第二个查询则不包含。ORDER BY id 该列已建立索引。id 尽管结构相似且列上存在索引,但第一个查询的执行时间明显长于第二个查询。id
我最初认为两个查询的操作将花费相似的时间,因为该列已建立索引。ORDER BYid 当我测量子查询 2 的执行时间时,两个查询确实显示出相似的性能。 但是,整个查询的执行时间差异很大。
为什么子查询 2 中的 会导致整个查询出现如此显着的性能差异,即使该列已建立索引?ORDER BYid 如何优化第一个查询以减少执行时间,同时保持?ORDER BY
该表有数千万行。 第一个查询的执行计划显示了子查询2.SORT ORDER BY中的操作 我想了解为什么当子查询性能相似时,完整查询性能差异如此之大。
我在 Oracle 中执行了 EXPLAIN PLAN 查询,但结果仅提供了有关执行时间的简化输出。
结果显示 INDEX FAST FULL SCAN 的执行存在差异。具体来说,尽管查询 1 结构相似,但查询 1 比查询 2 花费更多时间。
最快、最简单的解决方案应该是 row_limiting_clause 子句:
SELECT *
FROM coupang.PRODUCT
ORDER BY id
OFFSET 5000000 ROWS FETCH NEXT 30 ROWS ONLY;