Moving to next portion of syntax, which lets you controls histogram creation and its type.
Size clause has different options as given below:
You can specify number of buckets. It must be in range of 1 to 254. 1 denotes no histogram with base column statistics (i.e. minimal information required for the Optimizer) while 254 is highest allowable value.
Oracle Histogram is very nice feature to help CBO to make right decision while constructing execution plan. But many of DBA’s do not use it, assuming it is complex concept to use. In next few posts, I will try to simplify it, so that we can achieve maximum benefit from it.
What it Histogram & what is its purpose:
A histogram is a special type of column statistic that provides more detailed information about the data distribution in a table column. In simple words, it is a feature in CBO and it helps optimizer to determine how data are distributed/skewed within column. Predicates with skewed data are good candidates for histogram creation.
Basically CBO assumes uniform data distribution of data inside column across the distinct values. For the columns that contain skewed data, histogram helps to generate more accurate execution plans.
Below example will explain you significance of histograms:
I have a table ADI.SALES_ORDER with 100000rows with index SALES_ORDER_N1 on column GENERATED.
GENERATEDcolumn has 4 distinct values: A, B, Y, N. CBO will assume uniform data distribution across these values. So any query with column GENERATED as predicate will go for FTS, as CBO will assume it has to select 25% data from table.
But in reality data under column generated in skewed as given below:
I gathered fresh statistics without histogram on table as shown below:
Now will compare execution plan with different values for predicate:
As expected this query is going for FTS, as it has to select approx. 80% of data.
But I will expect query to pick index in case of GENERATED=’N’ as it will just select less than 1% of rows from table.
But NO its still going for FTS 😦 & it is due to CBO’s default behavior.
Now here Histogram should come into picture:
Now I will once again compare plans:
As expected following query is going for FTS, as it has to select approx. 80% of data.
But following query has picked up index due to creation of histogram. 🙂
In this post, we focused on what is histogram & why it is used.
Recently I was performing database reorg operation on one of pre-prod environment with traditional way of table/lob movement followed by index rebuild. After moving all segments from current tablespace to new, I was ready to drop original one.
SQL> select count(0) from dba_segments where tablespace_name='MY_TABLESPACE';
And it errored out!!!
SQL> DROP TABLESPACE MY_TABLESPACE INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE MY_TABLESPACE INCLUDING CONTENTS AND DATAFILES
*ERROR at line 1:
ORA-14404: partitioned table contains partitions in a different tablespace
As first step, I tried purging dba_recyclebin, but it didn’t help.
1. An attempt was made to drop a tablespace which contains tables whose partitions or subpartitions are not completely contained in this tablespace.
2. This can happen due to deferred segment creation introduced in 11.2.
First cause was matching my case:
I tried finding out tables whose partitions were spread across other partitions along with tablespace MY_TABLESPACE & moved to it to new tablespace as well:
SELECT 'alter table '|| table_owner|| '.'|| table_name|| ' move partition '|| partition_name|| ' tablespace MY_TABLESPACE_NEW;' FROM (SELECT DISTINCT table_name, partition_name FROM dba_tab_partitions WHERE tablespace_name = 'MY_TABLESPACE') a, dba_tab_partitions b WHERE b.tablespace_name <> 'MY_TABLESPACE' AND a.table_name = b.table_name;
After moving all affected table partitions, I once again tried dropping tablespace: MY_TABLESPACE. It once again failed with same error: ORA-14404.
Then I found same issue with some of index partitions as well, for which I used following command:
Once indexes were rebuild, I was able to drop tablespace MY_TABLESPACE without any issues 🙂
Note: You may also get ORA-14407 is some cases, wherein sub-partitions are the issue, for which you will use above commands just with sub-partitions views.
Just to elaborate seconds possible cause of this error: deferred segment creation:
The Oracle Database 11.2 includes a new space allocation method. When you create a non-partitioned heap table, the table segment creation is deferred to the first row insert. This functionality is enabled by default with the initialization parameter DEFERRED_SEGMENT_CREATION set to TRUE.So in simple words, if you have set this parameter to value TRUE, particular table will be populated in dba_tables once created, but will not be populated in dba_segments unless we insert a row to it. So in the case of defered segments, you will not be able to drop tablespace.
In this post, we are discussing about performance issue which I faced with EXPDP schema backup.
We have a production database, for which we take daily EXPDP schema backup before EOD starts. The control-m job configuration has made in such a way that EOD will not start until schema level EXPDP backup gets complete. From last month, EXPDP backup started taking considerable time. Initially it used to take hardly 15 minutes, and all of sudden it started taking 90 minutes, in turn causing delays in start of EOD. Application team raised problem ticket with us for the same issue.
I did basic tuning, like increasing PGA or excluding statistics, but none of it helped me to minimize backup time. Then I thought of observing wait event for EXPDP master & slave processes. It was “Streams AQ: enqueue blocked on low memory”. Of course it was something to related to performance issue I was observing.
I did check for memory configuration of database & found memory is configured with automatic management:
If you see above output, due to sudden growth in shared pool size, other components like large pool, db cache & streams pool have shrunk.
I tried to dig in history backup logfiles & found, till 6th Jan 2017, backups were running fine. So lack of streams pool memory is causing EXPDP to run longer.
So as to resolve this issue, I switched from automatic memory to manual one & allocated 200 MB to streams pool. Post memory configuration changes, EXPDP performance was back to normal.
According to MOS note, There is a restriction on index data length. It depends on the db_block_size. For 8K Oracle block size,it is 6398. Also the restriction depends on the actual Oracle data block size rather than the DB_BLOCK_SIZE database initialization parameter. That means that when using tablespaces with a different block size, the restriction depends on the actual block_size of the tablespace used for the index storage.
So I checked table definition to get details about datatype for columns used in table.
SQL> desc TEST_USER.DEMO_TABLE
Name Null? Type
----------------------------------------- -------- ----------------------------
As per table definition creating index on two columns SEQUENCEGROUP & SEQUENCENUMBER would make index key length to 8000 which is more than 6398, which is causing failure in index creation.
So how to resolve this: So we have 2 ways
1. Limit column key length if possible:
So in my case, I altered both column datatypes to VARCHAR2(3000), so that index key length was restricted to 6000.Post table alteration, I was able to created index successfully.
2. Create index in tablespace with bigger block size:
So you can create tablespace with block size 16K/32K, and then create index in this new tablespace.
Now we need to understand why we have this restriction:
As per Oracle 8i documentation, index key size is limited by the value of db_block_size, because a key value may not span multiple blocks. In fact, it is required that any index block must contain at least TWO index entries per block. Therefore, the maximum key length for an index will be less than half of the DB_BLOCK_SIZE. The Oracle 8i Administrator’s Guide states that the maximum size of a single index entry is approximately one-half the data block size. However, when considering that we must also leave space in the block according to PCTFREE, INITRANS, and space for block overhead (Block Header, ROW Directory, Table Directory, etc) the actual space that can be used for the Index key is actually just over 1/3 of the DB_BLOCK_SIZE.
Oracle 9.2 onward, restriction on index data length has been increased from 3218 to 6398. So from 9.2 – 11g we have scope to accommodate more, but there is still a restriction and we cannot create the index beyond it.
This was due to some of the DLL files related to oracle on server were used by some of the active processes even after I had stopped all oracle related services. Even i tried rebooting whole server, but it didn’t help.
I did check related logfile so as to get more details about the error:
Such errors are very easy to fix on UNIX platform wherein we do have commands like ps, fuser or lsofto get details about the process accessing particular file. But what we can do for Windows platform.
I did check with widows admins to help me out here for identifying active processes. He told me about very intersting command “tasklist”.
Syntax: tasklist.exe /m <filename>
This command will give you details such as process name, PID & filename used by process as shown below:
So here I got the culprit. Now how to get rid of these processes. You can go to resource monitor under task manager to identify the process and then kill it as shown below:
Now you can apply patch without any issues.
As per my past experience, killing windows process manually can cause some serious issues after some time. So after killing any process manually on windows server, will recommend you to cleanly restart your server.