I have a datamart with 5 dimension table and a fact table.
I'm trying to clean a dimension table that has few rows (4000 rows). But, the fact table have millions rows (25GB)(Indexes and partitions).
When I try to delete a row in the table dimension, the process becomes very slow. It's just as slow despite the absence of relationship with a row in the fact table (cascade delete).
Is there any way to optimize this?. Thanks in advance.
Presumably, there is a cascading delete of some sort between the dimension table and the fact table.
Adding an index on the key column in the fact table may be sufficient. Then Oracle can immediately tell if/where any given value is.
If that doesn't work, drop the foreign key constraint altogether. Delete the unused values and add the constraint back in.
You could try these strategies as well :
create another copy of the fact table but, without the dim foreign key column of the table to be cleaned.
create fact_table_new as
select dim1_k, dim2_k, dim3_k, dim4_k, dim5_k (not this column), fact_1, fact_2, ...
from fact_table ;
or
update fact_table
set dim5_fk_col = null
where dim5_fk_col in (select k_col from dim5_table) ;
Related
I have an Oracle table in a live production environment and the table is over half a gig in size. Is it possible to change this normal Oracle table from being heap organised to index organised or is this only achievable by moving the data from this table to another new table which is index organised? Either way, I would be grateful if you could you please list the steps involved in this procedure.
There is no way to alter a table to make it index-organized table. Instead you can redefine the table(using DBMS_REDEFINITION)or can create new table using CTAS.
Example:
create table t2 (
id number, first_name varchar2(20),
constraint pk_id primary key (id)
)
organization index
as select * from t1;
I never used DBMS_REDEFINITION but with CTAS it is not only step to create table if it is production.
List all indexes, constraints, foreign keys and so on based on system views
Prepare create index, constraints and alter foreign keys statements. prepare list of triggers, procedures that depend on table.
Create table as select (consider lock before that step if you can)
Create all indexes, constraints with prepared statements from step 2
Swap table names and swap foreign keys (this step may cause some errors if you hit insert on foreign keys (if you expect it on that time you should lock the table and tables referencing by foreign key).
Compile dependent objects from 2 (if you locked tables unlock here)
(if you haven't locked on step 3) Insert into table select * from new minus select * from old; or if you have timstamp of inserting row just insert new rows.
I hope the list is complete.
I need to update the primary key of a large Index Organized Table (20 million rows) on Oracle 11g.
Is it possible to do this using multiple UPDATE queries? i.e. Many smaller UPDATEs of say 100,000 rows at a time. The problem is that one of these UPDATE batches could temporarily produce a duplicate primary key value (there would be no duplicates after all the UPDATEs have completed.)
So, I guess I'm asking is it somehow possible to temporarily disable the primary key constraint (but which is required for an IOT!) or alter the table temporarily some other way. I can have exclusive and offline access to this table.
The only solution I can see is to create a new table and when complete, drop the original table and rename the new table to the original table name.
Am I missing another possibility?
You can't disable / drop the primary key constraint from an IOT, since it is a unique index by definition.
When I need to change an IOT like this, I either do a CTAS (create table as) for a new plain heap table, do my maintenance, and then CTAS a new IOT.
Something like:
create table t_temp as select * from t_iot;
-- do maintenance
create table t_new_iot as select * from t_temp;
If, however, you need to simply add or join a new field to the existing key, you can do this in one step by creating the new IOT structure, then populating directly from the old IOT with a query.
Unfortunately, this is one of the downsides to IOTs.
I would recommend following method:
Create new IOT table partitioned by system with single partition
with exactly same structure as current one.
Lock current IOT table to prevent any DML.
insert into new table as select from current table changing PK values in select. This step
could be repeated several times if needed. In this case it's better
to do it in another session to keep lock on original table.
Exchange partition of new table with original table.
Requirement : I have one huge table (say haivng lacs records) with duplicate entries for when we combine three columns value together. My requirement is to populate second different table having unique records (removing duplicates from first table).
For this requirement as we have to do bulk inserts in second table, I came across MERGE feature of oracle 10g, which is more optimize way for bulk insert. But when I tried this I am getting integrity constraint error for composite primary key(three cols that I mentioned above).
MERGE INTO 2ndTable e
USING firstTable h
ON (e.firstCol = h.firstCol and e.2ndCol = h.2ndCol and e.3rdCol = h.3rdCol)
WHEN NOT MATCHED THEN
INSERT VALUES (h.firstCol, h.2ndCol, h.3rdCol);
composite primary key for 2nd Table : e.firstCol, e.2ndCol, e.3rdCol
Please let me know your thought for this error OR the best way we can handle this bulk inserts removing duplicate records.
I have a table Customer_Chronics in Oracle 11g.
The table has three key columns as shown below :
branch_code
customer_id
period
I have partitioned by table by list of branch_code, and now I'm having dilemma. Which is better:
Create unique index indexNumberOne on Customer_Chronics (PERIOD, CUSTOMER_ID);
Create unique index indexNumberTwo on Customer_Chronics (branch_code, PERIOD, CUSTOMER_ID);
The actual data must be unique by period, customer_id. If I put a unique index only on these two columns Oracle will check all partitions on the table when inserting new records?
The only way to enforce uniqueness is with a unique constraint on the columns of interest. So that's your first option. The database will check all values across all partitions it this case. But as it's a unique index that shouldn't take too long no matter how big the table gets (if that's your concern).
Yes, If you put unique index on that two columns only, Oracle will create a global index and will check all partitions. This is one of challenges I face sometime because we prefer local indexs for big tables (small tables should be OK).
I have this table in an Oracle DB which has a primary key defined on 3 of the data columns. I want to drop the primary key constraint to allow rows with duplicate data for those columns, and create a new column, 'id', to contain an auto-incrementing integer ID for these rows. I know how to create a sequence and trigger to add an auto-incrementing ID for new rows added to the table, but is it possible to write a PL/SQL statement to add unique IDs to all the rows that are already in the table?
Once you have created the sequence:
update mytable
set id = mysequence.nextval;
If you're just using an integer for a sequence you could update the id with the rownum. e.g.
update
table
set id = rownum
You then need to reset the sequence to the next valid id.
Is this what you need?
UPDATE your_table
SET id = your_seq.nextval;
This assumes you don't care what order your primary keys are in.
First you should check your PCTFREE... is there enough room for every row to get longer?
If you chose a very small PCTFREE or your data has lots of lenght-increasing updates, you might begin chaining every row to do this as an update.
You almost certainly better to do this as a CTAS.
Create table t2 as select seq.nextval, t1.* from t1.
drop t1
rename t2 to t1.