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

planner: remove some restrictions for global index #53509

Merged
merged 2 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions pkg/planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -2046,15 +2046,17 @@ func (ds *DataSource) convertToIndexScan(prop *property.PhysicalProperty,
}

if ds.tableInfo.GetPartitionInfo() != nil {
// Add sort items for index scan for merge-sort operation between partitions.
byItems := make([]*util.ByItems, 0, len(prop.SortItems))
for _, si := range prop.SortItems {
byItems = append(byItems, &util.ByItems{
Expr: si.Col,
Desc: si.Desc,
})
// Add sort items for index scan for merge-sort operation between partitions, only required for local index.
if !is.Index.Global {
byItems := make([]*util.ByItems, 0, len(prop.SortItems))
for _, si := range prop.SortItems {
byItems = append(byItems, &util.ByItems{
Expr: si.Col,
Desc: si.Desc,
})
}
cop.indexPlan.(*PhysicalIndexScan).ByItems = byItems
}
cop.indexPlan.(*PhysicalIndexScan).ByItems = byItems
if cop.tablePlan != nil && ds.SCtx().GetSessionVars().StmtCtx.UseDynamicPartitionPrune() {
if !is.Index.Global {
is.Columns, is.schema, _ = AddExtraPhysTblIDColumn(is.SCtx(), is.Columns, is.Schema())
Expand Down
10 changes: 0 additions & 10 deletions pkg/planner/core/indexmerge_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,6 @@ func (ds *DataSource) generateNormalIndexPartialPaths4DNF(
// the entire index merge is not valid anymore.
return nil, false, usedMap
}
// prune out global indexes.
itemPaths = slices.DeleteFunc(itemPaths, func(path *util.AccessPath) bool {
if path.Index != nil && path.Index.Global {
return true
}
return false
})
partialPath := buildIndexMergePartialPath(itemPaths)
if partialPath == nil {
// for this dnf item, we couldn't generate an index merge partial path.
Expand Down Expand Up @@ -889,9 +882,6 @@ func (ds *DataSource) generateIndexMerge4ComposedIndex(normalPathCnt int, indexM
var mvIndexPathCnt int
candidateAccessPaths := make([]*util.AccessPath, 0, len(ds.possibleAccessPaths))
for idx := 0; idx < normalPathCnt; idx++ {
if ds.possibleAccessPaths[idx].Index != nil && ds.possibleAccessPaths[idx].Index.Global {
continue
}
if (ds.possibleAccessPaths[idx].IsTablePath() &&
!ds.isInIndexMergeHints("primary")) ||
(!ds.possibleAccessPaths[idx].IsTablePath() &&
Expand Down
55 changes: 55 additions & 0 deletions tests/integrationtest/r/globalindex/multi_valued_index.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
set tidb_enable_global_index = true;
CREATE TABLE `customers` (
`id` bigint(20),
`name` char(10) DEFAULT NULL,
`custinfo` json DEFAULT NULL,
KEY idx(`id`),
UNIQUE KEY `zips` ((cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)))
) PARTITION BY HASH (`id`) PARTITIONS 5;
INSERT INTO customers VALUES (1, 'pingcap', '{"zipcode": [1,2]}');
INSERT INTO customers VALUES (2, 'pingcap', '{"zipcode": [2,3]}');
Error 1062 (23000): Duplicate entry '2' for key 'customers.zips'
INSERT INTO customers VALUES (2, 'pingcap', '{"zipcode": [3,3,4]}');
INSERT INTO customers VALUES (3, 'pingcap', '{"zipcode": [5,6]}');
explain select * from customers where (1 member of (custinfo->'$.zipcode'));
id estRows task access object operator info
IndexMerge_11 1.00 root partition:all type: union
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan_10(Probe) 1.00 cop[tikv] table:customers keep order:false, stats:pseudo
select * from customers where (1 member of (custinfo->'$.zipcode'));
id name custinfo
1 pingcap {"zipcode": [1, 2]}
explain select * from customers where json_overlaps("[1, 3, 7, 10]", custinfo->'$.zipcode');
id estRows task access object operator info
Selection_5 3.20 root json_overlaps(cast("[1, 3, 7, 10]", json BINARY), json_extract(globalindex__multi_valued_index.customers.custinfo, "$.zipcode"))
└─IndexMerge_17 4.00 root partition:all type: union
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan_10(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[3,3], keep order:false, stats:pseudo
├─IndexRangeScan_12(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[7,7], keep order:false, stats:pseudo
├─IndexRangeScan_14(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[10,10], keep order:false, stats:pseudo
└─TableRowIDScan_16(Probe) 4.00 cop[tikv] table:customers keep order:false, stats:pseudo
select * from customers where json_overlaps("[1, 3, 7, 10]", custinfo->'$.zipcode');
id name custinfo
1 pingcap {"zipcode": [1, 2]}
2 pingcap {"zipcode": [3, 3, 4]}
explain select * from customers where json_overlaps("[1, 6, 10]", custinfo->'$.zipcode') and id > 1;
id estRows task access object operator info
Selection_5 2.40 root json_overlaps(cast("[1, 6, 10]", json BINARY), json_extract(globalindex__multi_valued_index.customers.custinfo, "$.zipcode"))
└─IndexMerge_20 1.00 root partition:all type: union
├─IndexRangeScan_12(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan_14(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[6,6], keep order:false, stats:pseudo
├─IndexRangeScan_16(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[10,10], keep order:false, stats:pseudo
└─Selection_19(Probe) 1.00 cop[tikv] gt(globalindex__multi_valued_index.customers.id, 1)
└─TableRowIDScan_18 3.00 cop[tikv] table:customers keep order:false, stats:pseudo
select * from customers where json_overlaps("[1, 6, 10]", custinfo->'$.zipcode') and id > 1;
id name custinfo
3 pingcap {"zipcode": [5, 6]}
explain select /*+ USE_INDEX_MERGE(customers, idx, zips) */* from customers where (1 member of (custinfo->'$.zipcode')) and id > 0;
id estRows task access object operator info
IndexMerge_9 0.33 root partition:all type: intersection
├─IndexRangeScan_5(Build) 3333.33 cop[tikv] table:customers, index:idx(id) range:(0,+inf], keep order:false, stats:pseudo
├─IndexRangeScan_6(Build) 1.00 cop[tikv] table:customers, index:zips(cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan_8(Probe) 0.33 cop[tikv] table:customers keep order:false, stats:pseudo
select /*+ USE_INDEX_MERGE(customers, idx, zips) */* from customers where (1 member of (custinfo->'$.zipcode')) and id > 0;
id name custinfo
1 pingcap {"zipcode": [1, 2]}
28 changes: 28 additions & 0 deletions tests/integrationtest/t/globalindex/multi_valued_index.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
set tidb_enable_global_index = true;
CREATE TABLE `customers` (
`id` bigint(20),
`name` char(10) DEFAULT NULL,
`custinfo` json DEFAULT NULL,
KEY idx(`id`),
UNIQUE KEY `zips` ((cast(json_extract(`custinfo`, _utf8'$.zipcode') as unsigned array)))
) PARTITION BY HASH (`id`) PARTITIONS 5;

INSERT INTO customers VALUES (1, 'pingcap', '{"zipcode": [1,2]}');
--error 1062
INSERT INTO customers VALUES (2, 'pingcap', '{"zipcode": [2,3]}');
INSERT INTO customers VALUES (2, 'pingcap', '{"zipcode": [3,3,4]}');
INSERT INTO customers VALUES (3, 'pingcap', '{"zipcode": [5,6]}');

explain select * from customers where (1 member of (custinfo->'$.zipcode'));
select * from customers where (1 member of (custinfo->'$.zipcode'));

explain select * from customers where json_overlaps("[1, 3, 7, 10]", custinfo->'$.zipcode');
--sorted_result
select * from customers where json_overlaps("[1, 3, 7, 10]", custinfo->'$.zipcode');

explain select * from customers where json_overlaps("[1, 6, 10]", custinfo->'$.zipcode') and id > 1;
--sorted_result
select * from customers where json_overlaps("[1, 6, 10]", custinfo->'$.zipcode') and id > 1;

explain select /*+ USE_INDEX_MERGE(customers, idx, zips) */* from customers where (1 member of (custinfo->'$.zipcode')) and id > 0;
select /*+ USE_INDEX_MERGE(customers, idx, zips) */* from customers where (1 member of (custinfo->'$.zipcode')) and id > 0;