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);
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;
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)
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
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);
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.
Thanks Christo, that is quite interesting.
And more to the point, will probably quite useful to know.
Thank you, will give a try
I’m trying to issue a create index that is a subset from a previous index. The explain plan for this new index creation shows that the previous, already created index, is been using in the plan. Ok, this is normal and usual.
But I don’t wan’t this. I’m trying to use the NO_INDEX hint in the CREATE INDEX command to disable the previous index access. But it’s been ignored.
As your post was the only one (up to now) I found about hints on CREATE INDEX commands I’m seeking for help here. If you have any previous experience with this, or wan’t to make a try, please share your comments