set tidb_cost_model_version=1; drop table if exists t; create table t (a int primary key, b int, c int, d int, e int, f int); create index tb on t (b); create index tc on t (c); create index td on t (d); load stats 's/explain_indexmerge_stats_t.json'; explain format = 'brief' select * from t where a < 50 or b < 50; id estRows task access object operator info IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (a < 50 or b < 50) and f > 100; id estRows task access object operator info IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─Selection(Probe) 98.00 cop[tikv] gt(test.t.f, 100) └─TableRowIDScan 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where b < 50 or c < 50; id estRows task access object operator info IndexMerge 98.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false set session tidb_enable_index_merge = on; explain format = 'brief' select * from t where a < 50 or b < 50; id estRows task access object operator info IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (a < 50 or b < 50) and f > 100; id estRows task access object operator info IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─Selection(Probe) 98.00 cop[tikv] gt(test.t.f, 100) └─TableRowIDScan 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where a < 50 or b < 5000000; id estRows task access object operator info TableReader 4999999.00 root data:Selection └─Selection 4999999.00 cop[tikv] or(lt(test.t.a, 50), lt(test.t.b, 5000000)) └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where b < 50 or c < 50; id estRows task access object operator info IndexMerge 98.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where b < 50 or c < 5000000; id estRows task access object operator info TableReader 4999999.00 root data:Selection └─Selection 4999999.00 cop[tikv] or(lt(test.t.b, 50), lt(test.t.c, 5000000)) └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where a < 50 or b < 50 or c < 50; id estRows task access object operator info IndexMerge 147.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 147.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (b < 10000 or c < 10000) and (a < 10 or d < 10) and f < 10; id estRows task access object operator info IndexMerge 0.00 root type: union ├─TableRangeScan(Build) 9.00 cop[tikv] table:t range:[-inf,10), keep order:false ├─IndexRangeScan(Build) 9.00 cop[tikv] table:t, index:td(d) range:[-inf,10), keep order:false └─Selection(Probe) 0.00 cop[tikv] lt(test.t.f, 10), or(lt(test.t.b, 10000), lt(test.t.c, 10000)) └─TableRowIDScan 18.00 cop[tikv] table:t keep order:false explain format="dot" select * from t where (a < 50 or b < 50) and f > 100; dot contents digraph IndexMerge_12 { subgraph cluster12{ node [style=filled, color=lightgrey] color=black label = "root" "IndexMerge_12" } subgraph cluster8{ node [style=filled, color=lightgrey] color=black label = "cop" "TableRangeScan_8" } subgraph cluster9{ node [style=filled, color=lightgrey] color=black label = "cop" "IndexRangeScan_9" } subgraph cluster11{ node [style=filled, color=lightgrey] color=black label = "cop" "Selection_11" -> "TableRowIDScan_10" } "IndexMerge_12" -> "TableRangeScan_8" "IndexMerge_12" -> "IndexRangeScan_9" "IndexMerge_12" -> "Selection_11" } set session tidb_enable_index_merge = off; explain format = 'brief' select /*+ use_index_merge(t, primary, tb, tc) */ * from t where a <= 500000 or b <= 1000000 or c <= 3000000; id estRows task access object operator info IndexMerge 3560000.00 root type: union ├─TableRangeScan(Build) 500000.00 cop[tikv] table:t range:[-inf,500000], keep order:false ├─IndexRangeScan(Build) 1000000.00 cop[tikv] table:t, index:tb(b) range:[-inf,1000000], keep order:false ├─IndexRangeScan(Build) 3000000.00 cop[tikv] table:t, index:tc(c) range:[-inf,3000000], keep order:false └─TableRowIDScan(Probe) 3560000.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, tb, tc) */ * from t where b < 50 or c < 5000000; id estRows task access object operator info IndexMerge 4999999.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 4999999.00 cop[tikv] table:t, index:tc(c) range:[-inf,5000000), keep order:false └─TableRowIDScan(Probe) 4999999.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, tb, tc) */ * from t where (b < 10000 or c < 10000) and (a < 10 or d < 10) and f < 10; id estRows task access object operator info IndexMerge 0.00 root type: union ├─IndexRangeScan(Build) 9999.00 cop[tikv] table:t, index:tb(b) range:[-inf,10000), keep order:false ├─IndexRangeScan(Build) 9999.00 cop[tikv] table:t, index:tc(c) range:[-inf,10000), keep order:false └─Selection(Probe) 0.00 cop[tikv] lt(test.t.f, 10), or(lt(test.t.a, 10), lt(test.t.d, 10)) └─TableRowIDScan 19978.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, tb) */ * from t where b < 50 or c < 5000000; id estRows task access object operator info TableReader 4999999.00 root data:Selection └─Selection 4999999.00 cop[tikv] or(lt(test.t.b, 50), lt(test.t.c, 5000000)) └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ no_index_merge(), use_index_merge(t, tb, tc) */ * from t where b < 50 or c < 5000000; id estRows task access object operator info TableReader 4999999.00 root data:Selection └─Selection 4999999.00 cop[tikv] or(lt(test.t.b, 50), lt(test.t.c, 5000000)) └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, primary, tb) */ * from t where a < 50 or b < 5000000; id estRows task access object operator info IndexMerge 4999999.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 4999999.00 cop[tikv] table:t, index:tb(b) range:[-inf,5000000), keep order:false └─TableRowIDScan(Probe) 4999999.00 cop[tikv] table:t keep order:false set session tidb_enable_index_merge = on; drop table if exists t; CREATE TABLE t ( `id` int(11) NOT NULL, `aid` bigint, `c1` varchar(255) DEFAULT NULL, `c2` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `aid_c1` (`aid`,`c1`), KEY `aid_c2` (`aid`,`c2`) ); desc select /*+ USE_INDEX_MERGE(t, aid_c1, aid_c2) */ * from t where (aid = 1 and c1='aaa') or (aid = 2 and c2='bbb'); id estRows task access object operator info IndexMerge_8 8.08 root type: union ├─IndexRangeScan_5(Build) 0.10 cop[tikv] table:t, index:aid_c1(aid, c1) range:[1 "aaa",1 "aaa"], keep order:false, stats:pseudo ├─IndexRangeScan_6(Build) 0.10 cop[tikv] table:t, index:aid_c2(aid, c2) range:[2 "bbb",2 "bbb"], keep order:false, stats:pseudo └─TableRowIDScan_7(Probe) 8.08 cop[tikv] table:t keep order:false, stats:pseudo