From 68b5e0658c103e524b9879f6ed62fbd8afa8f417 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Thu, 18 Nov 2021 14:48:37 +0800 Subject: [PATCH] fix by comments Signed-off-by: guo-shaoge --- cmd/explaintest/r/index_merge.result | 116 --------------------------- cmd/explaintest/t/index_merge.test | 59 -------------- executor/index_merge_reader_test.go | 72 +++++++++++++++++ executor/mem_reader.go | 7 +- 4 files changed, 75 insertions(+), 179 deletions(-) delete mode 100644 cmd/explaintest/r/index_merge.result delete mode 100644 cmd/explaintest/t/index_merge.test diff --git a/cmd/explaintest/r/index_merge.result b/cmd/explaintest/r/index_merge.result deleted file mode 100644 index 6233aba59afab..0000000000000 --- a/cmd/explaintest/r/index_merge.result +++ /dev/null @@ -1,116 +0,0 @@ -drop table if exists t1; -create table t1(c1 int, c2 int, c3 int, key(c1), key(c2), key(c3)); -begin; - -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -IndexMerge_9 1841.86 root -├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo -├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo -└─Selection_8(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_7 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 - -insert into t1 values(1, 1, 1); -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -Projection_5 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3 -└─UnionScan_6 1841.86 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) - └─IndexMerge_11 1841.86 root - ├─IndexRangeScan_7(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect one row -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 -1 1 1 - -update t1 set c3 = 100 where c3 = 1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -Projection_5 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3 -└─UnionScan_6 1841.86 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) - └─IndexMerge_11 1841.86 root - ├─IndexRangeScan_7(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 - -delete from t1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -Projection_5 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3 -└─UnionScan_6 1841.86 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) - └─IndexMerge_11 1841.86 root - ├─IndexRangeScan_7(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 -commit; - - -# test partialPlan is TableScan. -drop table if exists t1; -create table t1(c1 int, c2 int, c3 int, primary key(c1), key(c2), key(c3)); -begin; - -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -IndexMerge_9 1106.67 root -├─TableRangeScan_5(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo -├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo -└─Selection_8(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_7 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 - -insert into t1 values(1, 1, 1); -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -UnionScan_6 1106.67 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) -└─IndexMerge_11 1106.67 root - ├─TableRangeScan_7(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect one row -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 -1 1 1 - -update t1 set c3 = 100 where c3 = 1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -UnionScan_6 1106.67 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) -└─IndexMerge_11 1106.67 root - ├─TableRangeScan_7(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 - -delete from t1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -id estRows task access object operator info -UnionScan_6 1106.67 root lt(test.t1.c3, 10), or(lt(test.t1.c1, 10), lt(test.t1.c2, 10)) -└─IndexMerge_11 1106.67 root - ├─TableRangeScan_7(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─Selection_10(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10) - └─TableRowIDScan_9 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo -//// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -c1 c2 c3 -commit; diff --git a/cmd/explaintest/t/index_merge.test b/cmd/explaintest/t/index_merge.test deleted file mode 100644 index 784eabe96f696..0000000000000 --- a/cmd/explaintest/t/index_merge.test +++ /dev/null @@ -1,59 +0,0 @@ -drop table if exists t1; -create table t1(c1 int, c2 int, c3 int, key(c1), key(c2), key(c3)); - -begin; ---echo -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -insert into t1 values(1, 1, 1); -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect one row -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -update t1 set c3 = 100 where c3 = 1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -delete from t1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -commit; - ---echo ---echo ---echo # test partialPlan is TableScan. -drop table if exists t1; -create table t1(c1 int, c2 int, c3 int, primary key(c1), key(c2), key(c3)); - -begin; ---echo -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -insert into t1 values(1, 1, 1); -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect one row -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -update t1 set c3 = 100 where c3 = 1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; - ---echo -delete from t1; -explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; ---echo //// expect empty -select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10; -commit; - diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 51620b861a94a..b3bcdfe605701 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -170,3 +170,75 @@ func (s *testSuite1) TestPartitionTableRandomIndexMerge(c *C) { tk.MustQuery("select /*+ USE_INDEX_MERGE(tpk, a, b) */ * from tpk where " + cond).Sort().Check(result) } } + +func (s *testSuite1) TestIndexMergeInTransaction(c *C) { + tk := testkit.NewTestKitWithInit(c, s.store) + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 int, c2 int, c3 int, pk int, key(c1), key(c2), key(c3), primary key(pk));") + tk.MustExec("begin;") + // Expect two IndexScan(c1, c2). + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows( + "IndexMerge_9 1841.86 root ", + "├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", + "└─Selection_8(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10)", + " └─TableRowIDScan_7 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) + // Expect one IndexScan(c2) and one TableScan(pk). + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows( + "IndexMerge_9 1106.67 root ", + "├─TableRangeScan_5(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", + "└─Selection_8(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10)", + " └─TableRowIDScan_7 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo")) + + // Test with normal key. + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("insert into t1 values(1, 1, 1, 1);") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustExec("update t1 set c3 = 100 where c3 = 1;") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("delete from t1;") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + + // Test with primary key, so the partialPlan is TableScan. + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("insert into t1 values(1, 1, 1, 1);") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustExec("update t1 set c3 = 100 where c3 = 1;") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("delete from t1;") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("commit;") + + // Test partition table. + tk.MustExec("drop table if exists t1;") + tk.MustExec(`create table t1(c1 int, c2 int, c3 int, pk int, part int, key(c1), key(c2), key(c3), primary key(pk, part)) + partition by range(part) ( + partition p0 values less than (10), + partition p1 values less than (20), + partition p2 values less than (maxvalue))`) + tk.MustExec("begin;") + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;").Check(testkit.Rows()) + + tk.MustExec("insert into t1 values(1, 1, 1, 1, 1);") + tk.MustExec("insert into t1 values(11, 11, 11, 11, 11);") + tk.MustExec("insert into t1 values(21, 21, 21, 21, 21);") + tk.MustExec("insert into t1 values(31, 31, 31, 31, 31);") + res := tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;").Sort() + res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;").Sort() + res.Check(testkit.Rows("1 1 1 1 1", "11 11 11 11 11")) + + tk.MustExec("update t1 set c3 = 100 where c3 = 1;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows("11 11 11 11 11")) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows("11 11 11 11 11")) + + tk.MustExec("delete from t1;") + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 20 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows()) + res = tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 20 or c2 < 20) and c3 < 20;") + res.Check(testkit.Rows()) + tk.MustExec("commit;") +} diff --git a/executor/mem_reader.go b/executor/mem_reader.go index d9eea0402173b..d43a07238c002 100644 --- a/executor/mem_reader.go +++ b/executor/mem_reader.go @@ -154,10 +154,9 @@ type memTableReader struct { colIDs map[int64]int buffer allocBuf pkColIDs []int64 - + cacheTable kv.MemBuffer // Used when extracting handles from row in memTableReader.getMemRowsHandle. handleCols plannercore.HandleCols - cacheTable kv.MemBuffer } type allocBuf struct { @@ -316,7 +315,7 @@ func (m *memTableReader) getRowData(handle kv.Handle, value []byte) ([][]byte, e return values, nil } -// Used when memIndexMergeReader.partialPlans[i] is TableScan. +// getMemRowsHandle is called when memIndexMergeReader.partialPlans[i] is TableScan. func (m *memTableReader) getMemRowsHandle() ([]kv.Handle, error) { rows, err := m.getMemRows() if err != nil { @@ -701,7 +700,7 @@ func unionHandles(kvRanges [][]kv.KeyRange, memIndexReaders []*memIndexReader, m return nil, errors.Errorf("len(kvRanges) should be equal to len(memIndexReaders)") } if len(memTableReaders) != len(memIndexReaders) { - return nil, errors.Errorf("len(kvRanges) should be equal to len(memIndexReaders)") + return nil, errors.Errorf("len(memTableReaders) should be equal to len(memIndexReaders)") } hMap := kv.NewHandleMap()