Beruflich Dokumente
Kultur Dokumente
QUERY OPTIMIZATION
In a previous article, we looked methods for fetching a row from a table along with a
number of rows either side of it. In the comments, Stew Ashton offered a solution using
the match_recognize clause introduced in 12c. How do the numbers stack up on the
performance of these different methods?
Let's find out!
To test this, I created a one million row table (with this script). For the tests I looked
for one row along with the five either side of it (:lname := 'Aaaq', :lvl := 5). Below is
each query along with its elapsed time and execution plans with selected statistics
(actual rows, buffer gets and elapsed time).
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 1/8
3/7/2020 Fetching a Row Plus N Either Side Performance Analysis | Oracle All Things SQL Blog
with boundaries as (
select prevr, nextr
from (
select person_id,
last_name,
lead(person_id,:lvl,0) over (order by person_id) as nextr,
lag(person_id,:lvl,0) over (order by person_id) as prevr
from test_people
)
where last_name like :lname
)
select /*+ gather_plan_statistics */emp.person_id, emp.last_name
from test_people emp
join boundaries b
on emp.person_id between b.prevr and b.nextr
order by emp.person_id;
Elapsed: 00:00:12.72
Ouch. That's taking twelve seconds to execute and features two full table scans!
Clearly this isn't going to be a workable solution unless you're certain the table will
only ever store a few hundred rows.
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 2/8
3/7/2020 Fetching a Row Plus N Either Side Performance Analysis | Oracle All Things SQL Blog
Elapsed: 00:00:04.78
That's significantly quicker - just less than five seconds. This is still doing a full table
scan, so as the data grows this is going to get slower. I think this is the most
straightforward query to read (at least, once you've got to grips with
match_recognize!) and may be good enough for ad-hoc analysis. If this is part of
an application you'll want something better.
Elapsed: 00:00:00.25
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 3/8
3/7/2020 Fetching a Row Plus N Either Side Performance Analysis | Oracle All Things SQL Blog
Nice! Execution time is well under one second - fast enough for most purposes.
Walk along the (primary key) index upwards until our boundary
Elapsed: 00:00:00.35
The execution time is marginally higher than the min/max approach. It uses fewer
buffer gets however. It also only accesses the person_pk index twice instead of four
times. If we ask for more rows each side, this solution should scale better.
So far I've assumed that names are unique. Clearly this isn't the case. What
happens if the search matches multiple names?
Uh-oh.
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 6/8
3/7/2020 Fetching a Row Plus N Either Side Performance Analysis | Oracle All Things SQL Blog
What do you think? Which method do you like best? Can you find a faster or more
elegant approach?
Comments ( 2 )
Recent Content
It's a rare event. Removing data from The Securing Account Details story in
a table. But every now and then you the previous blog post highlighted
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 7/8
3/7/2020 Fetching a Row Plus N Either Side Performance Analysis | Oracle All Things SQL Blog
may need to do a bit of spring two problems with SQL that uses
cleaning and clear down data. This... literals instead of bind variables:...
Site Map Legal Notices Terms of Use Privacy Cookie Preferences Ad Choices
https://blogs.oracle.com/sql/fetching-a-row-plus-n-either-side-performance-analysis 8/8