Drop Empty Partition. Are indexes marked as invalid? - oracle

I want to drop a partition that is empty but I am aware about oracle setting all indexes to unusable whenever you perform a partition DDL statement like DROP, therefore, I should add UPDATE GLOBAL INDEXES to the statement though it looks unnecessary.
Then I came up with this post where it says that it wont mark it as unusable so I decided to test it. The thing is that I tested it in two oracle versions and it worked different!
Having two instances:
DBa(Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production)
DBb(Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production)
In DBa it marked them as invalid and in DBb which contained the same data than the other db (cloned with exp/imp) it succeed to drop without marking them unusable.
Is it possible to explicitly tell Oracle that you want to keep the indexes usable because there is no data in the partition (without rebuilding the indexes) ?

So far I am not able to find out why it was marked as invalid in a placed but not in the other one but there is something to say in case someone have the same problem.
Run it always with UPDATE GLOBAL INDEXES since if the partition is empty it will take no time to perform the drop and it ensures that the indexes will not be marked as invalid. Therefore, there is no reason to hope that oracle won't mark them

May be you can try below, this maintains index validity during the drop.
ALTER TABLE t1 DROP PARTITION p5 UPDATE GLOBAL INDEXES;

yes .. use LOCAL indexes while creating indexes over partitioned table

Related

asynchronous global index maintenance for drop and truncate partition

We have a very large partitioned table that needs to drop partition periodically. The business system needs 7*24 hours of operation.
We use global index.
From the following article, we know that Oracle supports asynchronous index update.
https://oracle-base.com/articles/12c/asynchronous-global-index-maintenance-for-drop-and-truncate-partition-12cr1
But : "The actual index maintenance is performed at a later time"\
Does it affect the normal business when it is actually executed.( Query/Insert/Update/Delete )
No it doesn't, as you can read here (I supposed you are running 12.1 as you didn't specify database version and you linked 12.1 documentation).
The parts that are of interest to you are the following:
The partitions of tables containing local indexes are locked to prevent DML operations against the affect table partitions, except for an ONLINE MOVE operation. However, unlike the index maintenance for local indexes, any global index is still fully available for DML operations and does not affect the online availability of the OLTP system.
[...]
For example, dropping an old partition is semantically equivalent to deleting all the records of the old partition using the SQL DELETE statement. In the DML case, all index entries of the deleted data set have to be removed from any global index as a standard index maintenance operation, which does not affect the availability of an index for SELECT and DML operations.

DDL changes in last one month for a user in oracle

I want to know ddl(Eg. adding a column in table) changes for specific user after a specific date in oracle? One strategy is by querying 'user_objects' table. Is there any other way to do this?
Can i also find out what ddl(Eg. added column name in table) changes has been done after specific date?
Version - Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
Audit DDL statements on or before the specified date. Capture DDL statements with a DDL trigger. Use a source control and build management system to track the history of changes. Or, if you happen to have every archived log since the specified date, laboriously go through them looking for DDL statements (this will not be a fun exercise if the specified date isn't really recent).
Otherwise, no. You can certainly look at the last_ddl_time in user_objects. But there are DDL statements that aren't changes (GRANT is a DDL statement for example, PL/SQL objects get recompiled automatically when there is DDL on a dependent object, etc) that will update the last_ddl_time without being what most people would consider a change. Unless you enable auditing, the data dictionary isn't going to be able to tell you what DDL caused the last_ddl_time to change so you won't know whether it was something that you consider a change, whether there were multiple changes, or what those changes are. If you happen to be lucky enough that your new column has an index, you could potentially infer when it was added by looking at the creation date of the associated index.

Best way to add column with default value while under load

When adding a column to a table that has a default value and a constraint of not null. Is it better to run as a single statement or to break it into steps while the database is under load.
ALTER TABLE user ADD country VARCHAR2(4) DEFAULT 'GB' NOT NULL
VERSUS
ALTER TABLE user ADD country VARCHAR2(2)
UPDATE user SET country = 'GB'
COMMIT
ALTER TABLE user MODIFY country DEFAULT 'GB' NOT NULL
Performance depends on the Oracle version you use. Locks are generated anyway.
If version <= Oracle 11.1 then #1 does the same as #2. It is slow anyway.
Beginning with Oracle 11.2, Oracle introduced a great optimization for the first statement (one command doing it all). You don't need to change the command - Oracle just behaves differently. It stores the default value only in data dictionary instead of updating each physical row.
But I also have to say, that I encountered some bugs in the past related to this feature (in Oracle 11.2.0.1)
failure of traditional import if export was done with direct=Y
merge statement can throw an ORA-600 [13013] (internal oracle error)
a performance problem in queries using such tables
I think this issues are fixed in current version 11.2.0.3, so I can recommend to use this feature.
Some time ago we have evaluated possible solutions of the same problem. On our project we had to remove all indexes on table, perform altering and restore indexes back.
If your system needs to be using the table then DBMS_Redefinition is really your only choice.

Oracle alter index/rebuild

If I rebuild an unusable index using alter index x rebuild, will the execution plan for any SQL that used that index previously be re-evaluated?
I know that the statistics are re-calculated as part of the rebuild in the DB version I'm using - Oracle 10.2.0.4.0.
I don't want to use the dbms_stats package to force the issue on this, seeing as I've already got fresh stats!
since the index is currently unusable, no SQL query uses the index. When you collect statistics (either through a rebuild or the dbms_stats package), all statements against the base table will be reparsed (hard-parse) next time they are submitted. Plans may change due to the stats update.
Rebuilding an unusable index will therefore make it visible and usable by all statements, even those that have been previously parsed.

Can I detect the version of a table's DDL in Oracle?

In Informix, I can do a select from the systables table, and can investigate its version column to see what numeric version a given table has. This column is incremented with every DDL statement that affects the given table. This means I have the ability to see whether a table's structure has changed since the last time I connected.
Is there a similar way to do this in Oracle?
Not really. The Oracle DBA/ALL/USER_OBJECTS view has a LAST_DDL_TIME column, but it is affected by operations other than structure changes.
You can do that (and more) with a DDL trigger that keeps track of changes to tables. There's an interesting article with example here.
If you really want to do so, you'd have to use Oracle's auditing functions to audit the changes. It could be as simple as:
AUDIT ALTER TABLE WHENEVER SUCCESSFUL on [schema I care about];
That would at least capture the successfuly changes, ignoring drops and creates. Unfortunately, unwinding the stack of the table's historical strucuture by mining the audit trail is left as an exercise to the reader in Oracle, or to licensing the Change Management Pack.
You could also roll your own auditing by writing system-event triggers which are invoked on DDL statements. You'd end up having to write your own SQL parser if you really wantedto see what was changing.

Resources