Note that there are some explanatory texts on larger screens.

plurals
  1. POSpeed of paged queries in Oracle
    primarykey
    data
    text
    <p>This is a never-ending topic for me and I'm wondering if I might be overlooking something. Essentially I use two types of SQL statements in an application:</p> <ol> <li>Regular queries with a "fallback" limit</li> <li>Sorted and paged queries</li> </ol> <p>Now, we're talking about some queries against tables with several million records, joined to 5 more tables with several million records. Clearly, we hardly want to fetch all of them, that's why we have the above two methods to limit user queries.</p> <p><strong>Case 1</strong> is really simple. We just add an additional <code>ROWNUM</code> filter:</p> <pre><code>WHERE ... AND ROWNUM &lt; ? </code></pre> <p>That's quite fast, as Oracle's CBO will take this filter into consideration for its execution plan and probably apply a <code>FIRST_ROWS</code> operation (similar to the one enforced by the <code>/*+FIRST_ROWS*/</code> hint.</p> <p><strong>Case 2</strong>, however is a bit more tricky with Oracle, as there is no <code>LIMIT ... OFFSET</code> clause as in other RDBMS. So we nest our "business" query in a technical wrapper as such:</p> <pre><code>SELECT outer.* FROM ( SELECT * FROM ( SELECT inner.*, ROWNUM as RNUM, MAX(ROWNUM) OVER(PARTITION BY 1) as TOTAL_ROWS FROM ( [... USER SORTED business query ...] ) inner ) WHERE ROWNUM &lt; ? ) outer WHERE outer.RNUM &gt; ? </code></pre> <p>Note that the <code>TOTAL_ROWS</code> field is calculated to know how many pages we will have even without fetching all data. Now this paging query is usually quite satisfying. But every now and then (as I said, when querying 5M+ records, possibly including non-indexed searches), this runs for 2-3minutes.</p> <p><strong>EDIT</strong>: Please note, that a potential bottleneck is not so easy to circumvent, because of sorting that has to be applied before paging!</p> <p>I'm wondering, is that state-of-the-art simulation of <code>LIMIT ... OFFSET</code>, including <code>TOTAL_ROWS</code> in Oracle, or is there a better solution that will be faster by design, e.g. by using the <code>ROW_NUMBER()</code> window function instead of the <code>ROWNUM</code> pseudo-column?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload