Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support CreateIndex and IndexType::Normal & IndexType::Composite #154

Merged
merged 7 commits into from
Mar 11, 2024

Conversation

KKould
Copy link
Member

@KKould KKould commented Mar 10, 2024

What problem does this PR solve?

feat:

  • support CreateIndex and IndexType::Normal & IndexType::Composite
  • support IndexType::Composite range detach

Use combined indexes when querying with multiple conditions. Note that columns with equivalent conditions need to be placed in the front of the combined index. Here is an example: if the select* from t where c1 = 10 and c2 = 100 and c3 > 10 query is frequently used, consider creating a combined index Index cidx (c1, c2, c3), so that a index prefix can be constructed to scan by query conditions.

use RangeDetacher sequentially obtain the relevant columns in the composite index, and only when the previous one is of equal value can I detach the next column.

Case 1: There is an index with three columns a, b, c. When WHERE a = 1 AND b > 1, the range of a=1 and b >1 can be extracted. The index can use the composite index of a, b, c. (if WHERE a > 1 AND b = 1 then the index cannot be used)

Case 2: There are two indexes with one column a and three columns a, b, c. When WHERE (a = 1 AND b > 1) OR a > 1, the range of a AND b cannot be extracted, but at this time the range of a range can be extracted and is a >= 1, so you can use a single-column index with column a

Tips: Case 2 can use similar index merging to perform better queries, but this may be optimized later.

ref:

28156=> explain select * from t1 where c1 > 10 and c2 = 991; 
                                PLAN                                                                                                                                                                                               
---------------------------------------------------------------------
 Projection [t1.c1, t1.c2] [Project]                                +
   Filter ((t1.c1 > 10) && (t1.c2 = 991)), Is Having: false [Filter]+
     Scan t1 -> [c1, c2] [IndexScan By p_index => ((991, 10), +∞]
(1 row)


28156=> select * from t1 where c1 > 10 and c2 = 991;         
 c1  | c2                                                                                                                                                                                                                          
-----+-----
 990 | 991
(1 row)


28156=> insert into t1 values(10000000, 991);
--                                                                                                                                                                                                                                 
(0 rows)


28156=> explain select * from t1 where c1 > 10 and c2 = 991;
                                PLAN                                                                                                                                                                                               
---------------------------------------------------------------------
 Projection [t1.c1, t1.c2] [Project]                                +
   Filter ((t1.c1 > 10) && (t1.c2 = 991)), Is Having: false [Filter]+
     Scan t1 -> [c1, c2] [IndexScan By p_index => ((991, 10), +∞]
(1 row)


28156=> select * from t1 where c1 > 10 and c2 = 991;         
    c1    | c2                                                                                                                                                                                                                     
----------+-----
      990 | 991
 10000000 | 991
(2 rows)

Index Selection

create table and index

create table t1(id int primary key, c1 int, c2 int);

statement ok
copy t1 from 'tests/data/row_20000.csv' ( DELIMITER '|' );

statement ok
insert into t1 values(100000000, null, null);

statement ok
create unique index u_c1_index on t1 (c1);

statement ok
create index c2_index on t1 (c2);

statement ok
create index p_index on t1 (c1, c2);

statement ok
analyze table t1;
IndexMeta {
    id: 3,
    column_ids: [
        1,
        2,
    ],
    table_name: "t1",
    pk_ty: Integer,
    name: "p_index",
    ty: Composite,
}
|— Input SQL: select * from t1 where c1 is null and c2 is null;
 |— time spent: 936.4µs
IndexMeta {
    id: 1,
    column_ids: [
        1,
    ],
    table_name: "t1",
    pk_ty: Integer,
    name: "u_c1_index",
    ty: Unique,
}
|— Input SQL: select * from t1 where c1 > 0 and c1 < 8;
 |— time spent: 935.4µs
IndexMeta {
    id: 2,
    column_ids: [
        2,
    ],
    table_name: "t1",
    pk_ty: Integer,
    name: "c2_index",
    ty: Normal,
}
|— Input SQL: select * from t1 where c2 > 0 and c2 < 9;
 |— time spent: 864.6µs
|— Input SQL: drop table t1;
 |— time spent: 892.6579ms
-> Pass!

TODO

When the case is select * from t1 where (c1 = 7 or c1 = 10) and c2 < 2;, the range is (-inf, (10, 2)), in fact it is better to be ((7), (7) ,2)), ((10), (10, 2))

Code changes

  • Has Rust code change
  • Has CI related scripts change

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Note for reviewer

@KKould KKould self-assigned this Mar 10, 2024
@KKould KKould added the enhancement New feature or request label Mar 10, 2024
@KKould KKould merged commit 6bfa14a into KipData:main Mar 11, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant