Pythian Blog: Technical Track

Oracle's CREATE INDEX command can take a hint

Here's something really useful I discovered by accident when playing with Auto DOP (parallel_degree_policy) in 12c. The "create index" command can take a hint - in particular the PARALLEL hint. The syntax is as you would expect: [sql] create /*+PARALLEL*/ index tab_ind1 on tab(col1); [/sql] Of course, you can specify the number of parallel servers to be used by specifying PARALLEL(24) for example for 24 threads. The really interesting thing about using a hint vs. the documented syntax ( "create index tab_ind1 on tab(col1) parallel 24;") is that once created - the index doesn't have a default degree of parallelism. So you don't need a second command to make the index noparallel. Note that if you put the hint and use the "noparallel" attribute like so: [sql] create /*+PARALLEL*/ index tab_ind1 on tab(col1) noparallel; [/sql] Then no parallelism will be used. I tried using hints like FULL(t) to force an index create to use a full table scan instead of an existing index - but that doesn't seem to work. I discovered this under really interesting circumstances. I was testing some unrelated functionality that required some indexes created on my play table called CKK. Here's the SQL for the CKK table, which will create a 40 GB table with 2 rows per block: [sql] create table ckk nologging tablespace ckk as select rownum id, mod(rownum,5) mod5_id, mod(rownum,5000) mod5000_id, sysdate dt_fixed, sysdate - rownum/24/60 dt_dec, sysdate + rownum/24/60 dt_pos, sysdate + ora_hash(rownum,65,535)/24 dt_rand, sysdate+mod(rownum,10) dt_mod10, rpad('x',3500,'x') filler from (select rownum r from dual connect by level <= 10000) r1, (select rownum r from dual connect by level <= 1000) ; [/sql] Then when I attempted to create an index on the table in parallel, Oracle refused to do so: [sql] create index ckk$id on ckk(id) parallel 24; --DOES NOT run in parallel [/sql] Instead it created the index with 1 thread only, and then set the parallel degree policy to 24. I have tracked this problem down to the Auto DOP feature. If I turn it off via parallel_degree_policy=manual - the problem goes away. But I never expected this feature to turn off parallelism for index creation when explicitly requested. Here's the kicker - once any index is created on the table, future index creations will be automatically done in parallel, regardless if parallel was requested. For example, this index would be now created in parallel: [sql] create index ckk$mod5_id on ckk(mod5_id); [/sql] While before creating the index "ckk$id" - this index would refuse to get created in parallel - when using the parallel attribute. That's when I said to myself, "it's almost like there's a hint." I took the hint, and discovered it does work, and it works more consistently than the attribute.

No Comments Yet

Let us know what you think

Subscribe by email