Skip to content

When using a composite primary key in Oracle, it may be necessary to check the order of index fields. #89

@DaDaRobot

Description

@DaDaRobot

It's a corner case :
The constraint and index for a composite primary key in Oracle use a different order of fields , The current conversion rule is to maintain the consistency of the fields order between TiDB's primary key and Oracle's constraint, but this might potentially lead to some unexpected performance issues downstream.

create table t1(col1 number(10,0),col2 number(10,0),col3 varchar2(10));
create unique index idx1 on t1(col1,col2);
alter table t1 add primary key (col2,col1) using index idx1 ;

SQL> select to_char(dbms_metadata.get_ddl('TABLE','T1','SCOTT')) ddl from dual ;

DDL

CREATE TABLE "SCOTT"."T1"
( "COL1" NUMBER(10,0),
"COL2" NUMBER(10,0),
"COL3" VARCHAR2(10)
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
TABLESPACE "USERS"
CREATE UNIQUE INDEX "SCOTT"."IDX1" ON "SCOTT"."T1" ("COL1", "COL2")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
TABLESPACE "USERS"
ALTER TABLE "SCOTT"."T1" ADD PRIMARY KEY ("COL2", "COL1")
USING INDEX "SCOTT"."IDX1" ENABLE

select TABLE_NAME,CONSTRAINT_NAME,CONSTRAINT_TYPE,INDEX_NAME from dba_constraints where table_name='T1' ;
image

select * from dba_ind_columns where table_name='T1' order by INDEX_NAME,COLUMN_POSITION ;
image

The result of converting to TiDB syntax is:
Create Table: CREATE TABLE t1 (
col1 bigint(20) NOT NULL,
col2 bigint(20) NOT NULL,
col3 varchar(10) DEFAULT NULL,
PRIMARY KEY (col2,col1) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

explain select * from t1 where col1=1;
+-------------------------+----------+-----------+---------------+--------------------------------+
| id | estRows | task | access object | operator info |
+-------------------------+----------+-----------+---------------+--------------------------------+
| TableReader_7 | 10.00 | root | | data:Selection_6 |
| └─Selection_6 | 10.00 | cop[tikv] | | eq(test.t1.col1, 1) |
| └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
+-------------------------+----------+-----------+---------------+--------------------------------+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions