I need to change the tablespace where 7 indexes are created. This is a 3TB partitioned index. A new partition is created each day and then folded into months. The command I am running is
alter index myindex1 modify default attributes for partition
mypartition tablespace myNewIndexTablespace;
The error is
ORA-14288 index is not partitioned by composite range method Cause:
The index in a partition or subpartition maintenance operation command
must be partitioned by composite range method.
I am trying to figure out the best approach here considering these indexes are big and reside on 52 partitions.
I think that this means that you cannot define a default tablespace for an index partition if that partition does not contain subpartitions.
The reason for that would be that the default tablespace for an object is the one to which new partitions or subpartitions would be assigned on creation. If a table or index is not partitioned then of course it could not have a default tablespace for new partitions, and if a table or index partition is not subpartitioned then it cannot have a default tablespace for the addition of new subpartitions.
You probably want to:
alter index
myindex1
modify
default attributes
tablespace myNewIndexTablespace;
... and then rebuild the current index partitions to the new tablespace.
http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_1010.htm#i2129868
Related
We have a VLDB around 2TB and tables are partitioned on each date. We also have index mapping for these partitions. But for year 2019 all the data up to 01-Oct-2019 is getting into a single partition as due to a typo a single sub partition got created with a high value of 01/10/2019.
We are trying to correct this using Split Partition i.e. move data up to 10th Feb 2019 to single partition and then remove the empty partition and create single partitions for each date. This is working fine.
The issue is coming with index mapping as there are mappings already from 1st Oct to 31st Dec and we are not able to drop these. So we were trying to create mapping from 11 Feb till 30 Sep. The script for this is taking a very long time due to volume of data. And also the indexes goes into UNUSABLE state after this and when we try to rebuild it's taking ages!!
Is there any better way we can do it.
CODE SAMPLE-
CREATE TABLE My_Table (
id NUMBER(9,0) NOT NULL,
source_system VARCHAR(20),
eod_date NUMBER(9,0) NOT NULL,
other columns
)
TABLESPACE XYZ001td
PARTITION BY LIST (source_system)
SUBPARTITION BY RANGE (
eod_date
)
(
PARTITION p_XYZ VALUES ('XYZ')
NOCOMPRESS
(
SUBPARTITION XYZ_20181227 VALUES LESS THAN (20181228) TABLESPACE XYZ_20181227_td,
SUBPARTITION XYZ_20181228 VALUES LESS THAN (20181229) TABLESPACE XYZ_20181228_td,
SUBPARTITION XYZ_20181229 VALUES LESS THAN (20181230) TABLESPACE XYZ_20181229_td,
SUBPARTITION XYZ_20181230 VALUES LESS THAN (20181231) TABLESPACE XYZ_20181230_td,
SUBPARTITION XYZ_20181231 VALUES LESS THAN (20190101) TABLESPACE XYZ_20181231_td
**SUBPARTITION XYZ_20191001 VALUES LESS THAN (20191002) TABLESPACE XYZ_20191001_td,**
SUBPARTITION XYZ_20191002 VALUES LESS THAN (20191003) TABLESPACE XYZ_20191002_td,
SUBPARTITION XYZ_20191003 VALUES LESS THAN (20191004) TABLESPACE XYZ_20191003_td,
)
)
/
CREATE INDEX inx_my_table_01
ON My_table (
source_system,
eod_date
)
TABLESPACE XYZ001td
GLOBAL PARTITION BY HASH (
source_system,
eod_date
)
(
PARTITION XYZ_20181227
TABLESPACE XYZ_20181227_ti
LOGGING,
PARTITION XYZ_20181228
TABLESPACE XYZ_20181228_ti
LOGGING,
PARTITION XYZ_20181229
TABLESPACE XYZ_20181229_ti
LOGGING,
PARTITION XYZ_20181230
TABLESPACE XYZ_20181230_ti
LOGGING,
PARTITION XYZ_20181231
TABLESPACE XYZ_20181231_ti
LOGGING
)
i am not sure if i completely understand the problem. But i think following steps might help
Create a temp table and copy all 2019 data to that table
drop all 2019 partitions and indexes.
recreate partitions and re insert the data
create local indexes
We can not drop global hash-partitioned index
ORA-14330: Cannot drop a partition of a global hash-partitioned index
Is there any way to insert intermediate Index mapping without touching existing Index mapping
Trying to move composite index partitions from tablespace A to tablespace B.
First I have moved all subpartitions successfully using DDL
ALTER INDEX idx1 REBUILD SUBPARTITION "0001234567889_1" TABLESPACE tablespace1 ONLINE PARALLEL;
dba_ind_subpartitions is now empty on originating tablespace. However indexes in dba_ind_partitions are still pointing to old tablespace. How do i change the tablespace of composite partitioned index?
I have tried rebuilding the indexes unsuccessfull:
SQL> ALTER INDEX idx1 REBUILD PARTITION "0001234567" TABLESPACE tablesspace1 ONLINE PARALLEL
*
ERROR at line 1:
ORA-14287: cannot REBUILD a partition of a composite partitioned index
EDIT:
Is it no possible to rebuild the indexes? Do i need to drop and recreate?
You have composite-partitioned table, so this is normal situation.
https://docs.oracle.com/database/121/VLDBG/GUID-E3F353CB-9748-44D4-B7B1-4BBAAF618D9D.htm
In your case on table or partition level you can modify default attributes.
https://docs.oracle.com/database/121/VLDBG/GUID-C003E6DB-3867-4407-86D2-A51F30AF07CC.htm#VLDBG1177
I am learning about tablespaces, but I am not sure what a segment of a tablespace constitutes. Is it safe to say that the following query displays all schema objects that can be moved to different tablespaces:
select distinct segment_type
from dba_segments;
Result:
SEGMENT_TYPE
------------------
LOBINDEX
INDEX PARTITION
TABLE SUBPARTITION
ROLLBACK
TABLE PARTITION
NESTED TABLE
LOB PARTITION
LOBSEGMENT
INDEX
TABLE
TYPE2 UNDO
CLUSTER
A segment represents the storage associated with an object such as a table or index. Segments reside in tablespaces.
You probably won't be moving rollback or undo segments, as those will be in their own dedicated tablespace and are system-managed in recent versions of Oracle.
I don't think there is a convenient way to move a cluster to a new tablespace, but then aside from the ones used internally for the data dictionary they are rarely used, so probably you won't have to deal with those either.
I have the following PL/SQL code:
DROP TABLE TAB_PARAM;
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE TAB_PARAM
(
TABLE_OWNER VARCHAR2(30) NOT NULL,
TABLE_NAME VARCHAR2(30) NOT NULL,
COLUMN_NAME VARCHAR2(30) NOT NULL,
PATTERN VARCHAR2(1024),
TYPE_METHODE VARCHAR2(30) NOT NULL,
SEPARATEUR VARCHAR2(20),
ID VARCHAR2(30),
CONSTRAINT PK_TAB_PARAM PRIMARY KEY (TABLE_OWNER,TABLE_NAME,COLUMN_NAME) USING INDEX TABLESPACE IND_PARC_256M NOLOGGING
)
TABLESPACE TAB_PARC_256M NOLOGGING NOCACHE NOMONITORING NOPARALLEL';
commit;
END;
/
I don't understand the part :
CONSTRAINT PK_TAB_PARAM PRIMARY KEY (TABLE_OWNER,TABLE_NAME,COLUMN_NAME) USING INDEX TABLESPACE IND_PARC_256M NOLOGGING
Nor the part:
TABLESPACE TAB_PARC_256M NOLOGGING NOCACHE NOMONITORING NOPARALLEL';
I know that it is setting the ID as primary key of TAB_PARAM but then I do not get the index part.
Can anyone help me understand this code please?
Sometimes you can create a table in a disposable way , for example you need to read data via sqlloader from file and insert in table , after that you will select all records from table . This operation doesnt need indexes and doesnt need primary key . Anyway it is always good to create primary key when you create a table and Oracle will create index for you . You can create more indexes whenever you want since the table was created . Now suppose you wanna update the table using where condition on a field who is not a primary key , it could be a better decision create an index on that field . In addition when you create indexes or table , you can associate tablespaces (created before) and could be good practice separate tablespaces for tables and indexes . All those operations are DDL Statements . In Oracle you can check datafiles , tables and indexes with those queries select * from dba_data_files; select * from dba_tables; select * from dba_indexes;
For primary key oracle implicitly creates unique index in table's tablespace.
This part USING INDEX TABLESPACE allow us to indicate tablespace for this implicitly index.
NOLOGGING - data is modified with minimal logging (to mark new extents invalid and to record dictionary changes).
NOCACHE - Oracle doesn't store blocks in the buffer cache.
NOPARALLEL - Parallel execution is not allowed on this table.(Default value)
NOMONITORING - Disable statistics collection. Now is deprecated. There is other mechanism to collect statistic
Edit. from oracle doc
Oracle Database uses an existing index if it contains a unique set of values before enforcing the primary key constraint. The existing
index can be defined as unique or nonunique. When a DML operation is
performed, the primary key constraint is enforced using this existing
index.
If there already index hitting the pk columns , oracle will used it, else then Oracle Database generates a unique index.
so you can create a primary key in oracle without an index if there was already index for that columns , specifying an index is for performance issue. The purpose of an index in a table is to 'read' the data faster.
From the oracle document
An index is a schema object that contains an entry for each value that
appears in the indexed column(s) of the table or cluster and provides
direct, fast access to rows.
As for the TABLESPACE, its where the database object exists, so when you create a table you specify in which tablespace you want it to exists. Read more here oracle document
As for NOLOGGING NOCACHE NOMONITORING, so the table not to be logged in redo logs or cached, also related to performance issue.
How can I alter a partitioned table (in Oracle 10g Database) to a new table space for not only the partitions but also the table itself? Which I mean is, I can do following without issues,
--sql
alter table abc move partition abc01 tablespace new_tablespace;
alter table abc move partition abc02 tablespace new_tablespace;
alter table abc move partition abc03 tablespace new_tablespace;
but somehow the table's definition is still associating with the old table space, and and I have moved all tables data off the old table space. If I query the dba_segment for the old table space, there is nothing there. My question is, may I drop the old table space, even no data in the data files in the old table space, but somehow those partitioned tables definitions still associating with the old table space?
Each partition must be moved, as you've discovered. If you want new partitions to be created in a different tablespace without specifying that new tablespace, you'd have to use the following:
alter table abc modify default attributes tablespace new_tablespace;