Unique Constraint performance - oracle

When having a table with 450 million records and a unique constraint (no primary key, just constraint made out of 6 columns), how can I improve its performance while inserting 5 million rows daily.
at the moment I just disable the constraint and enable it after the loading has finished. But this takes some time.
By the way, there is no unique index supporting the constraint... it will just get super huge

In case your import procedure ensures uniquenes of new rows you can enable the constraint with NOVALIDATE, then existing data in the table are not checked.
See here:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/clauses002.htm#SQLRF52204

Related

Unique constraint without index

let's say I have a large table.
This table not need to be queried, I just want to save the data inside for a while.
I want to prevent duplicates rows in the table, so I want to add an unique
constraint (or PK) on the table.
But the auto-created unique index is realy unnecessary.
I don't need it, and it's just wasting space in disk and require a maintenance
(regardless of the long time to create it).
Is there a way to create an unique constraint without index (any index - unique or nonunique)?
Thank you.
No, you can't have a UNIQUE constraint in Oracle without a corresponding index. The index is created automatically when the constraint is added, and any attempt to drop the index results in the error
ORA-02429: cannot drop index used for enforcement of unique/primary key
Best of luck.
EDIT
But you say "Let's say I have a large table". So how many rows are we talking about here? Look, 1TB SSD's are under $100. Quad-core laptops are under $400. If you're trying to minimize storage use or CPU burn by writing a bunch of code with minimal applicability to "save money" or "save time" my suggestion is that you're wasting both time and money. I repeat - ONE TERABYTE of storage costs the same as ONE HOUR of programmer time. A BRAND SPANKING NEW COMPUTER costs the same as FOUR LOUSY HOURS of programmer time. You are far, far better off doing whatever you can to minimize CODING TIME, rather than the traditional optimization targets of CPU time or disk space. Thus, I submit that the UNIQUE index is the low cost solution.
But the auto-created unique index is really unnecessary.
In fact, UNIQUEness in an Oracle Database is enforced/guaranteed via an INDEX. That's why your primary key constraints come with a UNIQUE INDEX.
Per the Docs
UNIQUE Key Constraints and Indexes
Oracle enforces unique integrity constraints with indexes.
Maybe Index-Organized Tables is what you need ?.
But strictly the index organized table is the table stored in the structure of the index - one can say that there is the index alone without the table, while yor requirement is to have the table without the index, so this is the opposite :)
CREATE TABLE some_name
(
col1 NUMBER(10) NOT NULL,
col2 NUMBER(10) NOT NULL,
col3 VARCHAR2(50) NOT NULL,
col4 VARCHAR2(50) NOT NULL,
CONSTRAINT pk_locations PRIMARY KEY (col1, col2)
)
ORGANIZATION INDEX

Enable Constraint - Peformance Impact

The below statement consumes a huge amount of time for a table containing 70 million records.
ALTER TABLE <table-name> ENABLE CONSTRAINT <constraint-name>
Does table scan all rows while enabling the constraint.
Even though the constraint got enabled, the process just hung for more than 5 hours.
Any ideas on how this can be optimized
As guys said before, depends on constrain type it is possibility skip validate existing data by ALTER TABLE ENABLE NOVALIDATE CONSTRAINT . And check this data by some additional procedure or query.
You can find documentation about that here https://docs.oracle.com/cd/B28359_01/server.111/b28310/general005.htm#ADMIN11546

Why unique index AND unique constraint (multi columns)?

So a table I am looking at has a unique constraint AND a unique index over multiple columns, and the exact same columns for both.
Is there a use for this or is the unique constraint redundant?
I agree that the existence of unique constraints and unique indexes does look redundant at first. It seems like a violation of Don't Repeat Yourself, allowing for confusing differences. But there are at least two reasons both exist - management features and allowing existing duplicates.
Management Features
In theory, a logical constraint can be created without worrying about the implementation. The constraint specifies what must be true, along with some options such as deferring the constraint until a commit.
In practice, constraints have such a large performance and storage penalty that the implementation must be considered. An index is required or else a single insert would require O(n) time instead of O(log(n)). Those indexes can take up a huge amount of space; someone might want to specify where it's stored, how it's compressed, etc.
Most of the time those features aren't important and using all the index defaults is fine. But sometimes storage and performance are critical and people will want to tweak the index without caring about the constraint.
Allow Existing Duplicates
There is at least one case where a unique constraint does not have a unique index. It's possible to allow existing duplicate valuess but prevent any future duplicates by setting the constraint to NOVALIDATE and using a non-unique index.
--Create table and insert duplicate values.
create table test1(a number);
insert into test1 values(1);
insert into test1 values(1);
commit;
--Add a non-validated unique constraint, with a non-unique index.
alter table test1
add constraint test1_uq unique(a)
using index (create /* Not unique!*/ index test1_uq on test1(a)) novalidate;
--Now multiple inserts raise: ORA-00001: unique constraint (JHELLER.TEST1_UQ) violated
insert into test1 values(2);
insert into test1 values(2);
The physical index must allow duplicates, but the logical constraint knows to not allow any more duplicates. Although this is a rare feature and I'm not sure if I've ever seen it in production code.

does Unique constraint on multiple columns has performance issues -Oracle

I am using Oracle database and I have a table for customers records and want to put a Unique key constraint on multiple varchar2 columns. like
CUST_ID (Number),
CUST_Name(varchar2),
Cust_N.I.C_NO(varchar2) will make a unique key.
when inserting new record through forms 6i, if ORA-00001 error comes, user will be informed that it was a DUPLICATED record.
Please advise me if there will be any database performance issue when records in this table will exceed 50000 or more.
If this is not a good practice to avoid inserting duplicate records, then please suggest any other approach.
regards.
Unique constraints are enforced though an index. So there are additional reads involved in the enforcement process. However, the performance impact of the constraint is minimal compared to the performance impact incurred by resolving duplicate keys in the database. Not to mention the business impact of such data corruption.
Besides, 50000 rows is a toy-sized table. Seriously, you won't be able to measure the difference of an insert with and without the constraints.

SQL Timeout and indices

Changing and finding stuff in a database containing a few dozen tables with around half a million rows in the big ones I'm running into timeouts quite often.
Some of these timeouts I don't understand. For example I got this table:
CREATE TABLE dbo.[VPI_APO]
(
[Key] bigint IDENTITY(1,1) NOT NULL CONSTRAINT [PK_VPI_APO] PRIMARY KEY,
[PZN] nvarchar(7) NOT NULL,
[Key_INB] nvarchar(5) NOT NULL,
) ON [PRIMARY]
GO
ALTER TABLE dbo.[VPI_APO] ADD CONSTRAINT [IX_VPI_APOKey_INB] UNIQUE NONCLUSTERED
(
[PZN],
[Key_INB]
) ON [PRIMARY]
GO
I often get timeouts when I search an item in this table like this (during inserting high volumes of items):
SELECT [Key] FROM dbo.[VPI_APO] WHERE ([PZN] = #Search1) AND ([Key_INB] = #Search2)
These timeouts when searching on the unique constraints happen quite often. I expected unique constraints to have the same benefits as indices, was I mistaken? Do I need an index on these fields, too?
Or will I have to search differently to benefit of the constraint?
I'm using SQL Server 2008 R2.
A unique constraint creates an index. Based on the query and the constraint defined you should be in a covering situation, meaning the index provides everything the query needs without a need to back to the cluster or the heap to retrieve data. I suspect that your index is not sufficiently selective or that your statistics are out of date. First try updating the statistics with sp_updatestats. If that doesn't change the behavior, try using UPDATE STATISTICS VPI_APO WITH FULL SCAN. If neither of those work, you need to examine the selectivity of the index using DBCC SHOW_STATISTICS.
My first thought is parameter sniffing.
If you're on SQL Server 2008, try "OPTIMIZE FOR UNKNOWN" rather than parameter masking
2nd thought is change the unique constrant to an index and INCLUDE the Key column explicitly. Internally they are the same, but as an index you have some more flexibility (eg filter, include etc)

Resources