I have to create an index on a table which has billion of records. at first i thought to create the index using PARALLEL 8 option since the server is running with 8 cores.
Now the question is, nioce the index is created, primary key is created using that index. Can i add NOPARALLEL option?
I have tried this statement
ALTER INDEX PK_TABLE_NAME_ NOPARALLEL;
But it doesn't work. can someone suggest me something?
That should work just fine:
SQL> create table t1
2 as
3 select rownum row_id
4 from dual
5 connect by level <= 100;
Table created.
SQL> create unique index i1 on t1(row_id) parallel 8;
Index created.
SQL> alter table t1
2 add constraint pk1 primary key(row_id)
using index i1;
Table altered.
SQL> alter index i1 noparallel;
Index altered.
I think you're looking for ALTER INDEX myidx parallel 1;
Source: http://www.dba-oracle.com/t_parallel_create_index.htm
Related
IF I FIRE A QUERY IN SQLPLS
DROP INDEX ord_customer_ix_demo;
This statement drops an index named ord_customer_ix_demo, which was created in "Compressing an Index: Example":
does this drop my table too?
I FIREd A QUERY IN SQLPLS
DROP INDEX ord_customer_ix_demo;
This statement drops an index named ord_customer_ix_demo, which was created in "Compressing an Index: Example":
i want to know does this drop my table too?
No, it won't drop a table.
Sample table:
SQL> create table demo as select level id from dual connect by level <= 5;
Table created.
Index on that table:
SQL> create index ord_ix_demo on demo (id);
Index created.
Table contents:
SQL> select * from demo;
ID
----------
1
2
3
4
5
Drop the index:
SQL> drop index ord_ix_demo;
Index dropped.
Is table still here? Yes:
SQL> select * from demo;
ID
----------
1
2
3
4
5
SQL>
I am trying to use the following statement for the Delete process and it has to delete around 23566424 Rows, but oracle takes almost 3 hours to complete the process and we have already created an index on " SCHEDULE_DATE_KEY" but still, the process is very slow.Can someone advise on how to make Deletes faster in oracle
DELETE
FROM
EDWSOURCE.SCHEDULE_DAY_F
WHERE
SCHEDULE_DATE_KEY >
(
SELECT
LAST_PAYROLL_DATE_KEY
FROM
EDWSOURCE.LAST_PAYROLL_DATE
WHERE
CURRENT_FLAG = 'Y'
);
I don't think any index will help here, probably Oracle will decide the best approach is a full table scan to delete 20M rows from 300M. It is deleting at a rate of over 2000 rows per second, which isn't bad. In fact any additional indexes will slow it down as it has to delete the row entry from the index as well.
A quicker approach could be to create a new table of the rows you want to keep, something like:
create table EDWSOURCE.SCHEDULE_DAY_F_KEEP
as
select * from EDWSOURCE.SCHEDULE_DAY_F
where SCHEDULE_DATE_KEY <=
(
SELECT
LAST_PAYROLL_DATE_KEY
FROM
EDWSOURCE.LAST_PAYROLL_DATE
WHERE
CURRENT_FLAG = 'Y'
);
Then recreate any constraints and indexes to use the new table.
Finally drop the old table and rename the new one.
You can try testing a filtered table move. This has an online clause. So you can do this while the application is still running.
Note 12.2 and later the indexes will remain valid. In earlier versions you will need to rebuild the indexes as they will become invalid. Good Luck
Move a Table
Create and populate a new test table.
DROP TABLE t1 PURGE;
CREATE TABLE t1 AS
SELECT level AS id,
'Description for ' || level AS description
FROM dual
CONNECT BY level <= 100;
COMMIT;
Check the contents of the table.
SELECT COUNT(*) AS total_rows,
MIN(id) AS min_id,
MAX(id) AS max_id
FROM t1;
TOTAL_ROWS MIN_ID MAX_ID
---------- ---------- ----------
100 1 100
SQL>
Move the table, filtering out rows with an ID value greater than 50.
ALTER TABLE t1 MOVE ONLINE
INCLUDING ROWS WHERE id <= 50;
Check the contents of the table.
SELECT COUNT(*) AS total_rows,
MIN(id) AS min_id,
MAX(id) AS max_id
FROM t1;
TOTAL_ROWS MIN_ID MAX_ID
---------- ---------- ----------
50 1 50
SQL>
The rows with an ID value between 51 and 100 have been removed.
As mentioned above if maybe best to PARTITION the table abs drop a PARTITION every N number of days as part of a daily task.
How to increment the value of the unique constraint column value in ORACLE, in the select statement.
For example, in a table 'BILLING_TABLE' - column BLNG_Sk is the unique key (Autoincremented).
So while inserting a new record into the BILLING_TABLE, for the column BLNG_SK we need to give the value (Which is the increment by 1 from the present max value.)
For example, if BLNG_SK max value is 12321.
new record should be 12322.
how to achieve this in Oracle?
Oracle has a SEQUENCE object which provides the functionality you require.
You create one using the CREATE SEQUENCE SQL statement.
The Oracle documentation provides all the required information and the documentation is available via Oracle's Web site.
Assuming you are on Oracle 12.1 or later, define it as an identity column and do not pass any value when inserting:
create table testtable
( test_id number generated always as identity
constraint testtable_pk primary key
, othercol varchar2(10) );
insert into testtable (othercol) values ('Demo');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
insert into testtable (othercol) values ('Demo #2');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
2 Demo #2
Try creating a sequence and a trigger. This is the case when you provide the value manually.
CREATE SEQUENCE dept_seq START WITH 12322;
Trigger definition:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON BILLING_TABLE
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
This question already has answers here:
How to create id with AUTO_INCREMENT on Oracle?
(18 answers)
Closed 8 years ago.
I am facing issue while inserting multiple row in one go into table because column id has primary key and its created based on sequence.
for ex:
create table test (
iD number primary key,
name varchar2(10)
);
insert into test values (123, 'xxx');
insert into test values (124, 'yyy');
insert into test values (125, 'xxx');
insert into test values (126, 'xxx');
The following statement creates a constraint violoation error:
insert into test
(
select (SELECT MAX (id) + 1 FROM test) as id,
name from test
where name='xxx'
);
This query should insert 3 rows in table test (having name=xxx).
You're saying that your query inserts rows with primary key ID based on a sequence. Yet, in your insert/select there is select (SELECT MAX (id) + 1 FROM test) as id, which clearly is not based on sequence. It may be the case that you are not using the term "sequence" in the usual, Oracle way.
Anyway, there are two options for you ...
Create a sequence, e.g. seq_test_id with the starting value of select max(id) from test and use it (i.e. seq_test_id.nextval) in your query instead of the select max(id)+1 from test.
Fix the actual subselect to nvl((select max(id) from test),0)+rownum instead of (select max(id)+1 from test).
Please note, however, that the option 2 (as well as your original solution) will cause you huge troubles whenever your code runs in multiple concurrent database sessions. So, option 1 is strongly recommended.
Use
insert into test (
select (SELECT MAX (id) FROM test) + rownum as id,
name from test
where name='xxx'
);
as a workaround.
Of course, you should be using sequences for integer-primary keys.
If you want to insert an ID/Primary Key value generated by a sequence you should use the sequence instead of selecting the max(ID)+1.
Usually this is done using a trigger on your table wich is executed for each row. See sample below:
CREATE TABLE "MY_TABLE"
(
"MY_ID" NUMBER(10,0) CONSTRAINT PK_MY_TABLE PRIMARY KEY ,
"MY_COLUMN" VARCHAR2(100)
);
/
CREATE SEQUENCE "S_MY_TABLE"
MINVALUE 1 MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 10 NOCACHE ORDER NOCYCLE NOPARTITION ;
/
CREATE OR REPLACE TRIGGER "T_MY_TABLE"
BEFORE INSERT
ON
MY_TABLE
REFERENCING OLD AS OLDEST NEW AS NEWEST
FOR EACH ROW
WHEN (NEWEST.MY_ID IS NULL)
DECLARE
IDNOW NUMBER;
BEGIN
SELECT S_MY_TABLE.NEXTVAL INTO IDNOW FROM DUAL;
:NEWEST.MY_ID := IDNOW;
END;
/
ALTER TRIGGER "T_MY_TABLE" ENABLE;
/
insert into MY_TABLE (MY_COLUMN) values ('DATA1');
insert into MY_TABLE (MY_COLUMN) values ('DATA2');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA3');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA4');
insert into MY_TABLE (MY_COLUMN) values ('DATA5');
/
select * from MY_TABLE;
I'm having a weird problem with index organized table. I'm running Oracle 11g standard.
i have a table src_table
SQL> desc src_table;
Name Null? Type
--------------- -------- ----------------------------
ID NOT NULL NUMBER(16)
HASH NOT NULL NUMBER(3)
........
SQL> select count(*) from src_table;
COUNT(*)
----------
21108244
now let's create another table and copy 2 columns from src_table
set timing on
SQL> create table dest_table(id number(16), hash number(20), type number(1));
Table created.
Elapsed: 00:00:00.01
SQL> insert /*+ APPEND */ into dest_table (id,hash,type) select id, hash, 1 from src_table;
21108244 rows created.
Elapsed: 00:00:15.25
SQL> ALTER TABLE dest_table ADD ( CONSTRAINT dest_table_pk PRIMARY KEY (HASH, id, TYPE));
Table altered.
Elapsed: 00:01:17.35
It took Oracle < 2 min.
now same exercise but with IOT table
SQL> CREATE TABLE dest_table_iot (
id NUMBER(16) NOT NULL,
hash NUMBER(20) NOT NULL,
type NUMBER(1) NOT NULL,
CONSTRAINT dest_table_iot_PK PRIMARY KEY (HASH, id, TYPE)
) ORGANIZATION INDEX;
Table created.
Elapsed: 00:00:00.03
SQL> INSERT /*+ APPEND */ INTO dest_table_iot (HASH,id,TYPE)
SELECT HASH, id, 1
FROM src_table;
"insert" into IOT takes 18 hours !!! I have tried it on 2 different instances of Oracle running on win and linux and got same results.
What is going on here ? Why is it taking so long ?
The APPEND hint is only useful for a heap-organized table.
When you insert into an IOT, I suspect that each row has to be inserted into the real index structure separately, causing a lot of re-balancing of the index.
When you build the index on a heap table, a temp segment is used and I'm guessing that this allows it to reduce the re-balancing overhead that would otherwise take place.
I suspect that if you created an empty, heap-organized table with the primary key, and did the same insert without the APPEND hint, it would take more like the 18 hours.
You might try putting an ORDER BY on your SELECT and see how that affects the performance of the insert into the IOT. It's not guaranteed to be an improvement by any means, but it might be.