Skip to Main Content
  • Questions
  • Parallel index creation on different table on same tablespace

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Atul.

Asked: April 15, 2025 - 12:52 pm UTC

Last updated: April 19, 2025 - 1:58 am UTC

Version: 19.0.0.0.0

Viewed 100+ times

You Asked

I’m having trouble with the parallel execution of an Oracle SQL query for creating indexes on separate table (assume each table have single index).

The performance boost isn’t even close to what I was hoping for. I therefore need your help in determining what to check for in the Oracle DB host in order to troubleshoot the issue.

Although, I found all SQL queries having WAIT_CLASS as “USER I/O”. I also did a check on IOPS through NetData UI on parallel index creation env, its max observed near ~24%.

Just to notice, we already aware that PARALLEL hint may help here, but we are looking further improvement on top of that.

Please let me know, whether any tunning on Oracle DB Side required or We can assume there won't be any benefit by executing index creation in parallel (even on different table) and we can only specify PARALLEL degree to enhance the performance.

and Connor said...

A nice easy place to start is
- Start a brand new session ( to reset all stats)
- create your index
- query the session statistics to see where you spent your time, eg


SQL> conn scott/tiger
Connected.
SQL> create index test_ix on t_lookup(par_date);

Index created.

SQL> select
  2     EVENT
  3    ,TOTAL_WAITS
  4    ,TOTAL_TIMEOUTS
  5    ,SECS
  6    ,rpad(to_char(100 * ratio_to_report(secs) over (), 'FM00.00') || '%',8)  pct
  7    from (
  8    select EVENT
  9    ,TOTAL_WAITS
 10    ,TOTAL_TIMEOUTS
 11    ,TIME_WAITED/100 SECS
 12    ,max_wait
 13  from v$session_event
 14  where sid = to_number(sys_context('USERENV','SID'))
 15  and event not like 'SQL*Net message%'
 16  union all
 17  select 'CPU', null, null, value/100 , 0 from v$sesstat
 18  where statistic# = ( select statistic# from v$statname where name = 'CPU used by this session')
 19  and sid = to_number(sys_context('USERENV','SID'))
 20  )
 21  order by 4;

EVENT                                                            TOTAL_WAITS TOTAL_TIMEOUTS       SECS PCT
---------------------------------------------------------------- ----------- -------------- ---------- -------------
Disk file operations I/O                                                   4              0          0 00.00%
log file switch completion                                                 2              0          0 00.00%
log file sync                                                              1              0          0 00.00%
db file sequential read                                                    3              0          0 00.00%
index (re)build lock or pin object                                         4              0          0 00.00%
events in waitclass Other                                                310              1        .02 00.25%
direct path write temp                                                  2447              0        .02 00.25%
direct path write                                                      13143              0        .07 00.88%
direct path read temp                                                   2925              0         .1 01.25%
db file scattered read                                                   295              0        .36 04.52%
CPU                                                                                                7.4 92.85%

11 rows selected.


So you can see in my case, 92% of the time was spent in CPU, 4% reading the data, 2% writing temporary data.

You can use that to get some insight as to where your time is being spent. That then becomes an input into how to proceed from there - post it back as a (nicely formatted) review

Rating

  (4 ratings)

Comments

Parallel index creation

Atul Kumar, April 16, 2025 - 1:19 pm UTC

As I am looking for improvement though Parallel index creation on separate tables, am I supposed to execute all index creation Query in parallel and collect this info when all are done ? Or something else.
Connor McDonald
April 19, 2025 - 1:54 am UTC

i've seen your next followup

Result after single index creation

Atul Kumar, April 17, 2025 - 7:16 am UTC

SQL> CREATE UNIQUE INDEX "<schma-name>"."<index-name>" ON "<schema-name>"."<table-name>" ("<column-name>") PCTFREE 10 INITRANS 2 MAXTRANS 167 COMPUTE STATISTICS STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "<table-space-name>";


Index created.

SQL> SELECT EVENT, TOTAL_WAITS, TOTAL_TIMEOUTS, SECS, RPAD(TO_CHAR(100 * RATIO_TO_REPORT(SECS) OVER (), 'FM00.00') || '%', 8) pct FROM (SELECT EVENT, TOTAL_WAITS, TOTAL_TIMEOUTS, TIME_WAITED/100 SECS, MAX_WAIT FROM V$SESSION_EVENT WHERE SID = TO_NUMBER(SYS_CONTEXT('USERENV','SID')) AND EVENT NOT LIKE 'SQL*Net message%' UNION ALL SELECT 'CPU', NULL, NULL, VALUE/100, 0 FROM V$SESSTAT WHERE STATISTIC# = (SELECT STATISTIC# FROM V$STATNAME WHERE NAME = 'CPU used by this session') AND SID = TO_NUMBER(SYS_CONTEXT('USERENV','SID'))) ORDER BY 4;

EVENT                                                            TOTAL_WAITS TOTAL_TIMEOUTS       SECS PCT
---------------------------------------------------------------- ----------- -------------- ---------- --------------------------------
SQL*Net break/reset to client                                              1              0          0 00.00%
index (re)build lock or pin object                                        20              0          0 00.00%
Disk file operations I/O                                                   4              0        .01 00.00%
log file sync                                                              5              0        .01 00.00%
direct path write temp                                                    73              0        .05 00.01%
direct path write                                                         44              0        .07 00.01%
events in waitclass Other                                               2113              1        .12 00.02%
direct path read temp                                                  30963              0      44.08 05.64%
direct path read                                                      130467              0     105.24 13.47%
CPU                                                                                             631.78 80.86%

10 rows selected.

SQL> 

Connor McDonald
April 19, 2025 - 1:58 am UTC

So you can see here that you spent around 13% of the time reading the table, but most of the time as CPU (doing all of the sorting).

This is a good thing, in the sense that, you didnt lose a lot of time in the IO layer.

This means there is probably scope now to look at parallelising the creation *as long as* you still have plenty of CPU head room at the OS level. Given that most servers are multi-core, and a serial 'create index' can only use 1 core, this is a reasonable assumption.


sqlmonitor report

Rajeshwaran Jeyabal, April 17, 2025 - 11:52 am UTC

Also while the create index statement executes, it is also possible to extract the sqlmonitor report to see the resource utilzation while it progress.
Connor McDonald
April 19, 2025 - 1:55 am UTC

agreed (if you have the license)

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.