You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

2120 lines
108 KiB

[
{
"Name": "TestHintScope",
"Cases": [
{
"SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ MERGE_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(test.t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)->Sort}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ INL_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "IndexJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ HASH_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "RightHashJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.c,test.t.a)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Best": "RightHashJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b",
"Best": "MergeInnerJoin{LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort->TableReader(Table(t))->Sort}(test.t.b,test.t.b)"
},
{
"SQL": "select /*+ STREAM_AGG() */ s, count(s) from (select /*+ HASH_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->Sort->StreamAgg->Projection"
},
{
"SQL": "select /*+ HASH_AGG() */ s, count(s) from (select /*+ STREAM_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Sort->Projection->StreamAgg->HashAgg->Projection"
},
{
"SQL": "select /*+ HASH_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->HashAgg->Projection"
},
{
"SQL": "select /*+ STREAM_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->Sort->StreamAgg->Projection"
}
]
},
{
"Name": "TestIndexHint",
"Cases": [
{
"SQL": "select /*+ USE_INDEX(t, c_d_e) */ * from t",
"Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`)"
},
{
"SQL": "select /*+ USE_INDEX(test.t, c_d_e) */ * from t",
"Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`)"
},
{
"SQL": "select /*+ IGNORE_INDEX(t, c_d_e) */ c from t order by c",
"Best": "TableReader(Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ IGNORE_INDEX(test.t, c_d_e) */ c from t order by c",
"Best": "TableReader(Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX(t, c_d_e) */ * from t t1",
"Best": "TableReader(Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t1` )"
},
{
"SQL": "select /*+ IGNORE_INDEX(t, c_d_e) */ t1.c from t t1 order by t1.c",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`)"
},
{
"SQL": "select /*+ USE_INDEX(t1, c_d_e) */ * from t t1",
"Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`)"
},
{
"SQL": "select /*+ IGNORE_INDEX(t1, c_d_e) */ t1.c from t t1 order by t1.c",
"Best": "TableReader(Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t1` )"
},
{
"SQL": "select /*+ USE_INDEX(t1, c_d_e), USE_INDEX(t2, f) */ * from t t1, t t2 where t1.a = t2.b",
"Best": "LeftHashJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))}(test.t.a,test.t.b)",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`), use_index(@`sel_1` `test`.`t2` `f`), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ IGNORE_INDEX(t1, c_d_e), IGNORE_INDEX(t2, f), HASH_JOIN(t1) */ * from t t1, t t2 where t1.a = t2.b",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.b)",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ USE_INDEX(t, c_d_e, f, g) */ * from t order by f",
"Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` `f`)"
},
{
"SQL": "select /*+ USE_INDEX(t) */ f from t where f > 10",
"Best": "TableReader(Table(t)->Sel([gt(test.t.f, 10)]))",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX(t, no_such_index) */ * from t",
"Best": "TableReader(Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ IGNORE_INDEX(t, no_such_index) */ * from t",
"Best": "TableReader(Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, f) */ c from t order by c",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`)"
},
{
"SQL": "select /*+ USE_INDEX(t, f), IGNORE_INDEX(t, f) */ c from t order by c",
"Best": "TableReader(Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, c_d_e) */ c from t order by c",
"Best": "TableReader(Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX(t, c_d_e, f), IGNORE_INDEX(t, c_d_e) */ c from t order by c",
"Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))->Sort",
"HasWarn": false,
"Hints": "use_index(@`sel_1` `test`.`t` `f`)"
}
]
},
{
"Name": "TestIndexMergeHint",
"Cases": [
{
"SQL": "select /*+ USE_INDEX_MERGE(t, c_d_e, f_g) */ * from t where c < 1 or f > 2",
"Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": false,
"Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f_g`)"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(t, primary, f_g) */ * from t where a < 1 or f > 2",
"Best": "IndexMergeReader(PartialPlans->[Table(t), Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": false,
"Hints": "use_index_merge(@`sel_1` `t` `primary`, `f_g`)"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2",
"Best": "IndexMergeReader(PartialPlans->[Table(t), Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": false,
"Hints": "use_index_merge(@`sel_1` `t` `primary`, `f_g`)"
},
{
"SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.a, 1), gt(test.t.f, 2))]))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(t1, c_d_e, f_g) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.a, 1), gt(test.t.f, 2))]))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(t) USE_INDEX_MERGE(t) */ * from t where c < 1 or f > 2",
"Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": false,
"Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f_g`)"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(db2.t) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(db2.t, c_d_e, f_g) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
}
]
},
{
"Name": "TestDAGPlanBuilderSimpleCase",
"Cases": [
{
"SQL": "select * from t t1 use index(c_d_e)",
"Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))"
},
{
"SQL": "select f from t use index() where f = 1",
"Best": "TableReader(Table(t)->Sel([eq(test.t.f, 1)]))"
},
{
"SQL": "select a from t where a between 1 and 2 order by c",
"Best": "TableReader(Table(t))->Sort->Projection"
},
{
"SQL": "select * from t where (t.c > 0 and t.c < 2) or (t.c > 4 and t.c < 6) or (t.c > 8 and t.c < 10) or (t.c > 12 and t.c < 14) or (t.c > 16 and t.c < 18)",
"Best": "IndexLookUp(Index(t.c_d_e)[(0,2) (4,6) (8,10) (12,14) (16,18)], Table(t))"
},
{
"SQL": "select * from t where (t.c > 0 and t.c < 1) or (t.c > 2 and t.c < 3) or (t.c > 4 and t.c < 5) or (t.c > 6 and t.c < 7) or (t.c > 9 and t.c < 10)",
"Best": "Dual"
},
{
"SQL": "select * from t where t.c = 1 and t.e = 1 order by t.b limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t))->TopN([test.t.b],0,1)"
},
{
"SQL": "select * from t where t.e_str is null",
"Best": "IndexLookUp(Index(t.e_d_c_str_prefix)[[NULL,NULL]], Table(t))"
},
{
"SQL": "select * from t where t.c is null",
"Best": "Dual"
},
{
"SQL": "select * from t where t.c = 1 and t.e = 1 order by t.e limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t))->TopN([test.t.e],0,1)"
},
{
"SQL": "select * from t where t.c = 1 and t.e = 1 order by t.d limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)])->Limit, Table(t))"
},
{
"SQL": "select c from t where t.c = 1 and t.e = 1 order by t.d limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)])->Limit)->Limit->Projection"
},
{
"SQL": "select c from t order by t.a limit 1",
"Best": "TableReader(Table(t)->Limit)->Limit->Projection"
},
{
"SQL": "select c from t order by t.a + t.b limit 1",
"Best": "TableReader(Table(t)->TopN([plus(test.t.a, test.t.b)],0,1))->Projection->TopN([Column#14],0,1)->Projection->Projection"
},
{
"SQL": "select c from t limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit"
},
{
"SQL": "select c from t where c = 1 limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->Limit)->Limit"
},
{
"SQL": "select c from t where c = 1",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])"
},
{
"SQL": "select c from t order by c",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])"
},
{
"SQL": "select c from t where c = 1 order by e",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Sort->Projection"
},
{
"SQL": "select c, b from t where c = 1 limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Limit, Table(t))->Projection"
},
{
"SQL": "select c, b from t where c = 1 and e = 1 and b = 1 limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)])->Limit)->Limit->Projection"
},
{
"SQL": "select c from t where c = 1 order by d, c",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Sort->Projection"
},
{
"SQL": "select c_str from t where e_str = '1' order by d_str, c_str",
"Best": "IndexLookUp(Index(t.e_d_c_str_prefix)[[\"1\",\"1\"]], Table(t))->Sort->Projection"
},
{
"SQL": "select c from t where t.c = 1 and t.a > 1 order by t.d limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->Sel([gt(test.t.a, 1)])->Limit)->Limit->Projection"
},
{
"SQL": "select c from t where t.c = 1 and t.d = 1 order by t.a limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[1 1,1 1]])->TopN([test.t.a],0,1)->Projection"
},
{
"SQL": "select * from t where t.c = 1 and t.a > 1 order by t.d limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([gt(test.t.a, 1)])->Limit, Table(t))"
},
{
"SQL": "select * from t use index(e_d_c_str_prefix) where t.c_str = 'abcdefghijk' and t.d_str = 'd' and t.e_str = 'e'",
"Best": "IndexLookUp(Index(t.e_d_c_str_prefix)[[\"e\" \"d\" \"abcdefghij\",\"e\" \"d\" \"abcdefghij\"]], Table(t)->Sel([eq(test.t.c_str, abcdefghijk)]))"
},
{
"SQL": "select * from t use index(e_d_c_str_prefix) where t.e_str = b'1110000'",
"Best": "IndexLookUp(Index(t.e_d_c_str_prefix)[[\"p\",\"p\"]], Table(t))"
},
{
"SQL": "select * from (select * from t use index() order by b) t left join t t1 on t.a=t1.a limit 10",
"Best": "IndexJoin{TableReader(Table(t)->TopN([test.t.b],0,10))->TopN([test.t.b],0,10)->TableReader(Table(t))}(test.t.a,test.t.a)->Limit"
},
{
"SQL": "select * from ((SELECT 1 a,3 b) UNION (SELECT 2,1) ORDER BY (SELECT 2)) t order by a,b",
"Best": "UnionAll{Dual->Projection->Dual->Projection}->HashAgg->Sort"
},
{
"SQL": "select * from ((SELECT 1 a,6 b) UNION (SELECT 2,5) UNION (SELECT 2, 4) ORDER BY 1) t order by 1, 2",
"Best": "UnionAll{Dual->Projection->Dual->Projection->Dual->Projection}->HashAgg->Sort->Sort"
},
{
"SQL": "select * from (select *, NULL as xxx from t) t order by xxx",
"Best": "TableReader(Table(t))->Projection"
},
{
"SQL": "select * from t use index(f) where f = 1 and a = 1",
"Best": "PointGet(Index(t.f)[KindInt64 1])->Sel([eq(test.t.a, 1)])"
},
{
"SQL": "select * from t2 use index(b) where b = 1 and a = 1",
"Best": "PointGet(Index(t2.b)[KindInt64 1])->Sel([eq(test.t2.a, 1)])"
}
]
},
{
"Name": "TestDAGPlanBuilderJoin",
"Cases": [
{
"SQL": "select * from t t1 join t t2 on t1.a = t2.c_str",
"Best": "LeftHashJoin{TableReader(Table(t))->Projection->TableReader(Table(t))->Projection}(Column#25,Column#26)"
},
{
"SQL": "select * from t t1 join t t2 on t1.b = t2.a",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.a)"
},
{
"SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a",
"Best": "LeftHashJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.b = t3.a",
"Best": "LeftHashJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.b,test.t.a)"
},
{
"SQL": "select * from t t1 join t t2 on t1.b = t2.a order by t1.a",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.a)"
},
{
"SQL": "select * from t t1 join t t2 on t1.b = t2.a order by t1.a limit 1",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.a)->Limit"
},
{
"SQL": "select /*+ TIDB_HJ(t1, t2) */ * from t t1 join t t2 on t1.b = t2.a order by t1.a limit 1",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.a)->TopN([test.t.a],0,1)"
},
{
"SQL": "select * from t t1 left join t t2 on t1.b = t2.a where 1 = 1 limit 1",
"Best": "IndexJoin{TableReader(Table(t)->Limit)->Limit->TableReader(Table(t))}(test.t.b,test.t.a)->Limit"
},
{
"SQL": "select * from t t1 join t t2 on t1.b = t2.a and t1.c = 1 and t1.d = 1 and t1.e = 1 order by t1.a limit 1",
"Best": "IndexJoin{PointGet(Index(t.c_d_e)[KindInt64 1 KindInt64 1 KindInt64 1])->TableReader(Table(t))}(test.t.b,test.t.a)->TopN([test.t.a],0,1)"
},
{
"SQL": "select * from t t1 join t t2 on t1.b = t2.b join t t3 on t1.b = t3.b",
"Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.b)->TableReader(Table(t))}(test.t.b,test.t.b)"
},
{
"SQL": "select * from t t1 join t t2 on t1.a = t2.a order by t1.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select * from t t1 left outer join t t2 on t1.a = t2.a right outer join t t3 on t1.a = t3.a",
"Best": "RightHashJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a and t1.b = 1 and t3.c = 1",
"Best": "IndexJoin{IndexJoin{TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select * from t where t.c in (select b from t s where s.a = t.a)",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)(test.t.c,test.t.b)"
},
{
"SQL": "select t.c in (select b from t s where s.a = t.a) from t",
"Best": "LeftHashJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.a)(test.t.c,test.t.b)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.b",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))->Sort}(test.t.a,test.t.b)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.a order by t2.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.b = t2.b order by t2.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->Sort->TableReader(Table(t))->Sort}(test.t.b,test.t.b)->Sort"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.a order by t2.a desc",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.b = t2.b order by t2.b desc",
"Best": "MergeInnerJoin{TableReader(Table(t))->Sort->TableReader(Table(t))->Sort}(test.t.b,test.t.b)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a",
"Best": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1, t t2, t t3 where t1.a = t2.b and t2.a = t3.b",
"Best": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))->Sort}(test.t.a,test.t.b)->Sort->TableReader(Table(t))->Sort}(test.t.a,test.t.b)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1, t t2, t t3 where t1.c = t2.c and t1.d = t2.d and t3.c = t1.c and t3.d = t1.d",
"Best": "MergeInnerJoin{MergeInnerJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)(test.t.d,test.t.d)->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)(test.t.d,test.t.d)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1, t t2, t t3 where t1.c = t2.c and t1.d = t2.d and t3.c = t1.c and t3.d = t1.d order by t1.c",
"Best": "MergeInnerJoin{MergeInnerJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)(test.t.d,test.t.d)->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)(test.t.d,test.t.d)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1 left outer join t t2 on t1.a = t2.a left outer join t t3 on t2.a = t3.a",
"Best": "MergeLeftOuterJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1 left outer join t t2 on t1.a = t2.a left outer join t t3 on t1.a = t3.a",
"Best": "MergeLeftOuterJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ * from t t1, t t2 where t1.a = t2.a",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1, t t2 where t1.a = t2.c",
"Best": "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.a,test.t.c)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
"Best": "IndexJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ t1.a, t2.a from t t1, t t2 where t1.a = t2.a order by t1.c",
"Best": "IndexJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ t1.a, t2.a from t t1, t t2 where t1.a = t2.a order by t2.c",
"Best": "IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select /*+ TIDB_INLJ(t1) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
"Best": "IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.c,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ * from t t1 left outer join t t2 on t1.a = t2.a and t2.b < 1",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t)->Sel([lt(test.t.b, 1)]))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ * from t t1 join t t2 on t1.d=t2.d and t2.c = 1",
"Best": "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.d,test.t.d)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1, t2) */ * from t t1 left outer join t t2 on t1.a = t2.b",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.b)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 right outer join t t2 on t1.a = t2.b",
"Best": "RightHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.b)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)",
"Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)",
"Best": "IndexJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.c=t2.c and t1.f=t2.f",
"Best": "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a = t2.a and t1.f=t2.f",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.f=t2.f and t1.a=t2.a",
"Best": "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a=t2.a and t2.a in (1, 2)",
"Best": "IndexJoin{BatchPointGet(Handle(t.a)[1 2])->TableReader(Table(t)->Sel([in(test.t.a, 1, 2)]))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.b=t2.c and t1.b=1 and t2.d > t1.d-10 and t2.d < t1.d+10",
"Best": "IndexJoin{TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.b=t2.b and t1.c=1 and t2.c=1 and t2.d > t1.d-10 and t2.d < t1.d+10",
"Best": "LeftHashJoin{IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))->IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))}(test.t.b,test.t.b)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t2.c > t1.d-10 and t2.c < t1.d+10",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.b = t2.c and t2.c=1 and t2.d=2 and t2.e=4",
"Best": "LeftHashJoin{TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->PointGet(Index(t.c_d_e)[KindInt64 1 KindInt64 2 KindInt64 4])}"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t2.c=1 and t2.d=1 and t2.e > 10 and t2.e < 20",
"Best": "LeftHashJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[(1 1 10,1 1 20)], Table(t))}"
}
]
},
{
"Name": "TestDAGPlanBuilderSubquery",
"Cases": [
{
"SQL": "select * from t where exists (select s.a from t s having sum(s.a) = t.a )",
"Best": "LeftHashJoin{TableReader(Table(t))->Projection->IndexReader(Index(t.f)[[NULL,+inf]]->StreamAgg)->StreamAgg}(Column#27,Column#25)"
},
{
"SQL": "select * from t where exists (select s.a from t s having sum(s.a) = t.a ) order by t.a",
"Best": "LeftHashJoin{TableReader(Table(t))->Projection->IndexReader(Index(t.f)[[NULL,+inf]]->StreamAgg)->StreamAgg}(Column#27,Column#25)->Sort"
},
{
"SQL": "select * from t where a in (select s.a from t s) order by t.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select * from t where exists (select s.a from t s where s.c in (select c from t as k where k.d = s.d) having sum(s.a) = t.a )",
"Best": "LeftHashJoin{TableReader(Table(t))->Projection->MergeSemiJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.c,test.t.c)(test.t.d,test.t.d)->Projection->StreamAgg}(Column#39,Column#37)"
},
{
"SQL": "select * from t where a in (select a from t) order by b",
"Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort"
},
{
"SQL": "select t.c in (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t",
"Best": "Apply{IndexReader(Index(t.c_d_e)[[NULL,+inf]])->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->StreamAgg}->Projection"
},
{
"SQL": "select (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Projection}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t order by t.a",
"Best": "MergeLeftOuterJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Projection}(test.t.a,test.t.a)->Projection->Projection"
}
]
},
{
"Name": "TestDAGPlanTopN",
"Cases": [
{
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b left join t t3 on t2.b = t3.b order by t1.a limit 1",
"Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t)->Limit)->Limit->TableReader(Table(t))}(test.t.b,test.t.b)->TopN([test.t.a],0,1)->TableReader(Table(t))}(test.t.b,test.t.b)->TopN([test.t.a],0,1)"
},
{
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b left join t t3 on t2.b = t3.b order by t1.b limit 1",
"Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t)->TopN([test.t.b],0,1))->TopN([test.t.b],0,1)->TableReader(Table(t))}(test.t.b,test.t.b)->TopN([test.t.b],0,1)->TableReader(Table(t))}(test.t.b,test.t.b)->TopN([test.t.b],0,1)"
},
{
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b left join t t3 on t2.b = t3.b limit 1",
"Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t)->Limit)->Limit->TableReader(Table(t))}(test.t.b,test.t.b)->Limit->TableReader(Table(t))}(test.t.b,test.t.b)->Limit"
},
{
"SQL": "select * from t where b = 1 and c = 1 order by c limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t)->Sel([eq(test.t.b, 1)]))->Limit"
},
{
"SQL": "select * from t where c = 1 order by c limit 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Limit, Table(t))"
},
{
"SQL": "select * from t order by a limit 1",
"Best": "TableReader(Table(t)->Limit)->Limit"
},
{
"SQL": "select c from t order by c limit 1",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit"
}
]
},
{
"Name": "TestDAGPlanBuilderBasePhysicalPlan",
"Cases": [
{
"SQL": "select * from t order by b limit 1 for update",
"Best": "TableReader(Table(t)->TopN([test.t.b],0,1))->TopN([test.t.b],0,1)->Lock",
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "update t set a = 5 where b < 1 order by d limit 1",
"Best": "TableReader(Table(t)->Sel([lt(test.t.b, 1)])->TopN([test.t.d],0,1))->TopN([test.t.d],0,1)->Update",
"Hints": "use_index(@`upd_1` `test`.`t` )"
},
{
"SQL": "update t set a = 5",
"Best": "TableReader(Table(t))->Update",
"Hints": "use_index(@`upd_1` `test`.`t` )"
},
{
"SQL": "delete /*+ TIDB_INLJ(t1, t2) */ t1 from t t1, t t2 where t1.c=t2.c",
"Best": "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)->Delete",
"Hints": "use_index(@`del_1` `test`.`t1` ), use_index(@`del_1` `test`.`t2` `c_d_e`), inl_join(@`del_1` `test`.`t2`)"
},
{
"SQL": "delete /*+ TIDB_SMJ(t1, t2) */ from t1 using t t1, t t2 where t1.c=t2.c",
"Best": "MergeInnerJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(test.t.c,test.t.c)->Delete",
"Hints": "use_index(@`del_1` `test`.`t1` `c_d_e`), use_index(@`del_1` `test`.`t2` `c_d_e`), merge_join(@`del_1` `test`.`t1`)"
},
{
"SQL": "update /*+ TIDB_SMJ(t1, t2) */ t t1, t t2 set t1.c=1, t2.a=1 where t1.a=t2.a",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Update",
"Hints": "use_index(@`upd_1` `test`.`t1` ), use_index(@`upd_1` `test`.`t2` ), merge_join(@`upd_1` `test`.`t1`)"
},
{
"SQL": "update /*+ TIDB_HJ(t1, t2) */ t t1, t t2 set t1.c=1, t2.a=1 where t1.a=t2.a",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Update",
"Hints": "use_index(@`upd_1` `test`.`t1` ), use_index(@`upd_1` `test`.`t2` ), hash_join(@`upd_1` `test`.`t1`)"
},
{
"SQL": "delete from t where b < 1 order by d limit 1",
"Best": "TableReader(Table(t)->Sel([lt(test.t.b, 1)])->TopN([test.t.d],0,1))->TopN([test.t.d],0,1)->Delete",
"Hints": "use_index(@`del_1` `test`.`t` )"
},
{
"SQL": "delete from t",
"Best": "TableReader(Table(t))->Delete",
"Hints": "use_index(@`del_1` `test`.`t` )"
},
{
"SQL": "delete from t use index(c_d_e) where b = 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t)->Sel([eq(test.t.b, 1)]))->Delete",
"Hints": "use_index(@`del_1` `test`.`t` `c_d_e`)"
},
{
"SQL": "insert into t select * from t where b < 1 order by d limit 1",
"Best": "TableReader(Table(t)->Sel([lt(test.t.b, 1)])->TopN([test.t.d],0,1))->TopN([test.t.d],0,1)->Insert",
"Hints": "use_index(@`sel_1` `test`.`t` )"
},
{
"SQL": "insert into t (a, b, c, e, f, g) values(0,0,0,0,0,0)",
"Best": "Insert",
"Hints": ""
},
{
"SQL": "select 1",
"Best": "Dual->Projection",
"Hints": ""
},
{
"SQL": "select * from t where false",
"Best": "Dual",
"Hints": ""
},
{
"SQL": "show tables",
"Best": "Show",
"Hints": ""
}
]
},
{
"Name": "TestDAGPlanBuilderUnion",
"Cases": [
{
"SQL": "select * from t union all select * from t",
"Best": "UnionAll{TableReader(Table(t))->TableReader(Table(t))}"
},
{
"SQL": "select * from t union all (select * from t) order by a ",
"Best": "UnionAll{TableReader(Table(t))->TableReader(Table(t))}->Sort"
},
{
"SQL": "select * from t union all (select * from t) limit 1",
"Best": "UnionAll{TableReader(Table(t)->Limit)->Limit->TableReader(Table(t)->Limit)->Limit}->Limit"
},
{
"SQL": "select a from t union all (select c from t) order by a limit 1",
"Best": "UnionAll{TableReader(Table(t)->Limit)->Limit->IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit}->TopN([Column#25],0,1)"
}
]
},
{
"Name": "TestDAGPlanBuilderUnionScan",
"Cases": null
},
{
"Name": "TestDAGPlanBuilderAgg",
"Cases": [
{
"SQL": "select distinct b from t",
"Best": "TableReader(Table(t))->HashAgg"
},
{
"SQL": "select count(*) from (select * from t order by b) t group by b",
"Best": "TableReader(Table(t))->Sort->StreamAgg"
},
{
"SQL": "select count(*), x from (select b as bbb, a + 1 as x from (select * from t order by b) t) t group by bbb",
"Best": "TableReader(Table(t))->Sort->Projection->StreamAgg"
},
{
"SQL": "select sum(a), avg(b + c) from t group by d",
"Best": "TableReader(Table(t)->HashAgg)->HashAgg"
},
{
"SQL": "select sum(distinct a), avg(b + c) from t group by d",
"Best": "TableReader(Table(t))->Projection->HashAgg"
},
{
"SQL": "select sum(e), avg(e + c) from t where c = 1 group by (c + d)",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->HashAgg)->HashAgg"
},
{
"SQL": "select sum(e), avg(e + c) from t where c = 1 group by c",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->StreamAgg)->StreamAgg"
},
{
"SQL": "select sum(e), avg(e + c) from t where c = 1 group by e",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]]->HashAgg)->HashAgg"
},
{
"SQL": "select sum(e), avg(b + c) from t where c = 1 and e = 1 group by d",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t))->Projection->HashAgg"
},
{
"SQL": "select sum(e), avg(b + c) from t where c = 1 and b = 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t)->Sel([eq(test.t.b, 1)]))->Projection->StreamAgg"
},
{
"SQL": "select sum(e) as k, avg(b + c) from t where c = 1 and b = 1 and e = 1 group by d order by k",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->Projection->StreamAgg->Sort"
},
{
"SQL": "select sum(e) as k, avg(b + c) from t where c = 1 and b = 1 and e = 1 group by c order by k",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->Projection->StreamAgg->Sort"
},
{
"SQL": "select sum(to_base64(e)) from t where c = 1",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection->StreamAgg"
},
{
"SQL": "select (select count(1) k from t s where s.a = t.a having k != 0) from t",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]]->Sel([1]))->Projection}(test.t.a,test.t.a)->Projection"
},
{
"SQL": "select sum(to_base64(e)) from t group by e,d,c order by c",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])->Projection->StreamAgg->Projection"
},
{
"SQL": "select sum(e+1) from t group by e,d,c order by c",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->StreamAgg)->StreamAgg->Projection"
},
{
"SQL": "select sum(to_base64(e)) from t group by e,d,c order by c,e",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])->Projection->StreamAgg->Sort->Projection"
},
{
"SQL": "select sum(e+1) from t group by e,d,c order by c,e",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->StreamAgg)->StreamAgg->Sort->Projection"
},
{
"SQL": "select count(*) from t group by g order by g limit 10",
"Best": "IndexReader(Index(t.g)[[NULL,+inf]]->StreamAgg)->StreamAgg->Limit->Projection"
},
{
"SQL": "select count(*) from t group by g limit 10",
"Best": "IndexReader(Index(t.g)[[NULL,+inf]]->StreamAgg)->StreamAgg->Limit"
},
{
"SQL": "select count(*) from t group by g order by g",
"Best": "IndexReader(Index(t.g)[[NULL,+inf]]->StreamAgg)->StreamAgg->Projection"
},
{
"SQL": "select count(*) from t group by g order by g desc limit 1",
"Best": "IndexReader(Index(t.g)[[NULL,+inf]]->StreamAgg)->StreamAgg->Limit->Projection"
},
{
"SQL": "select count(*) from t group by b order by b limit 10",
"Best": "TableReader(Table(t)->HashAgg)->HashAgg->TopN([test.t.b],0,10)->Projection"
},
{
"SQL": "select count(*) from t group by b order by b",
"Best": "TableReader(Table(t)->HashAgg)->HashAgg->Sort->Projection"
},
{
"SQL": "select count(*) from t group by b limit 10",
"Best": "TableReader(Table(t)->HashAgg)->HashAgg->Limit"
},
{
"SQL": "select sum(a.g), sum(b.g) from t a join t b on a.g = b.g group by a.g",
"Best": "MergeInnerJoin{IndexReader(Index(t.g)[[NULL,+inf]])->IndexReader(Index(t.g)[[NULL,+inf]])}(test.t.g,test.t.g)->Projection->StreamAgg"
},
{
"SQL": "select /*+ tidb_inlj(a,b) */ sum(a.g), sum(b.g) from t a join t b on a.g = b.g and a.g > 60 group by a.g order by a.g limit 1",
"Best": "IndexJoin{IndexReader(Index(t.g)[(60,+inf]])->IndexReader(Index(t.g)[[NULL,+inf]]->Sel([gt(test.t.g, 60)]))}(test.t.g,test.t.g)->Projection->StreamAgg->Limit->Projection"
},
{
"SQL": "select sum(a.g), sum(b.g) from t a join t b on a.g = b.g and a.a>5 group by a.g order by a.g limit 1",
"Best": "MergeInnerJoin{IndexReader(Index(t.g)[[NULL,+inf]]->Sel([gt(test.t.a, 5)]))->IndexReader(Index(t.g)[[NULL,+inf]])}(test.t.g,test.t.g)->Projection->StreamAgg->Limit->Projection"
},
{
"SQL": "select sum(d) from t",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->StreamAgg)->StreamAgg"
}
]
},
{
"Name": "TestRefine",
"Cases": [
{
"SQL": "select a from t where c is not null",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]])"
},
{
"SQL": "select a from t where c >= 4",
"Best": "IndexReader(Index(t.c_d_e)[[4,+inf]])->Projection"
},
{
"SQL": "select a from t where c <= 4",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,4]])->Projection"
},
{
"SQL": "select a from t where c = 4 and d = 5 and e = 6",
"Best": "PointGet(Index(t.c_d_e)[KindInt64 4 KindInt64 5 KindInt64 6])->Projection"
},
{
"SQL": "select a from t where d = 4 and c = 5",
"Best": "IndexReader(Index(t.c_d_e)[[5 4,5 4]])->Projection"
},
{
"SQL": "select a from t where c = 4 and e < 5",
"Best": "IndexReader(Index(t.c_d_e)[[4,4]]->Sel([lt(test.t.e, 5)]))->Projection"
},
{
"SQL": "select a from t where c = 4 and d <= 5 and d > 3",
"Best": "IndexReader(Index(t.c_d_e)[(4 3,4 5]])->Projection"
},
{
"SQL": "select a from t where d <= 5 and d > 3",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([le(test.t.d, 5) gt(test.t.d, 3)]))->Projection"
},
{
"SQL": "select a from t where c between 1 and 2",
"Best": "IndexReader(Index(t.c_d_e)[[1,2]])->Projection"
},
{
"SQL": "select a from t where c not between 1 and 2",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (2,+inf]])->Projection"
},
{
"SQL": "select a from t where c <= 5 and c >= 3 and d = 1",
"Best": "IndexReader(Index(t.c_d_e)[[3,5]]->Sel([eq(test.t.d, 1)]))->Projection"
},
{
"SQL": "select a from t where c = 1 or c = 2 or c = 3",
"Best": "IndexReader(Index(t.c_d_e)[[1,3]])->Projection"
},
{
"SQL": "select b from t where c = 1 or c = 2 or c = 3 or c = 4 or c = 5",
"Best": "IndexLookUp(Index(t.c_d_e)[[1,5]], Table(t))->Projection"
},
{
"SQL": "select a from t where c = 5",
"Best": "IndexReader(Index(t.c_d_e)[[5,5]])->Projection"
},
{
"SQL": "select a from t where c = 5 and b = 1",
"Best": "IndexLookUp(Index(t.c_d_e)[[5,5]], Table(t)->Sel([eq(test.t.b, 1)]))->Projection"
},
{
"SQL": "select a from t where not a",
"Best": "PointGet(Handle(t.a)0)"
},
{
"SQL": "select a from t where c in (1)",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection"
},
{
"SQL": "select a from t where c in ('1')",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection"
},
{
"SQL": "select a from t where c = 1.0",
"Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection"
},
{
"SQL": "select a from t where c in (1) and d > 3",
"Best": "IndexReader(Index(t.c_d_e)[(1 3,1 +inf]])->Projection"
},
{
"SQL": "select a from t where c in (1, 2, 3) and (d > 3 and d < 4 or d > 5 and d < 6)",
"Best": "Dual->Projection"
},
{
"SQL": "select a from t where c in (1, 2, 3) and (d > 2 and d < 4 or d > 5 and d < 7)",
"Best": "IndexReader(Index(t.c_d_e)[(1 2,1 4) (1 5,1 7) (2 2,2 4) (2 5,2 7) (3 2,3 4) (3 5,3 7)])->Projection"
},
{
"SQL": "select a from t where c in (1, 2, 3)",
"Best": "IndexReader(Index(t.c_d_e)[[1,1] [2,2] [3,3]])->Projection"
},
{
"SQL": "select a from t where c in (1, 2, 3) and d in (1,2) and e = 1",
"Best": "BatchPointGet(Index(t.c_d_e)[[KindInt64 1 KindInt64 1 KindInt64 1] [KindInt64 1 KindInt64 2 KindInt64 1] [KindInt64 2 KindInt64 1 KindInt64 1] [KindInt64 2 KindInt64 2 KindInt64 1] [KindInt64 3 KindInt64 1 KindInt64 1] [KindInt64 3 KindInt64 2 KindInt64 1]])->Projection"
},
{
"SQL": "select a from t where d in (1, 2, 3)",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([in(test.t.d, 1, 2, 3)]))->Projection"
},
{
"SQL": "select a from t where c not in (1)",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (1,+inf]])->Projection"
},
{
"SQL": "select a from t use index(c_d_e) where c != 1",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (1,+inf]])->Projection"
},
{
"SQL": "select a from t where c_str like ''",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"\",\"\"]])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abc\"]])->Projection"
},
{
"SQL": "select a from t where c_str not like 'abc'",
"Best": "IndexReader(Index(t.c_d_e_str)[[-inf,\"abc\") (\"abc\",+inf]])->Projection"
},
{
"SQL": "select a from t where not (c_str like 'abc' or c_str like 'abd')",
"Best": "IndexReader(Index(t.c_d_e_str)[[-inf,\"abc\") (\"abc\",\"abd\") (\"abd\",+inf]])->Projection"
},
{
"SQL": "select a from t where c_str like '_abc'",
"Best": "IndexReader(Index(t.c_d_e_str)[[NULL,+inf]]->Sel([like(test.t.c_str, _abc, 92)]))->Projection"
},
{
"SQL": "select a from t where c_str like 'abc%'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abd\")])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc_'",
"Best": "IndexReader(Index(t.c_d_e_str)[(\"abc\",\"abd\")]->Sel([like(test.t.c_str, abc_, 92)]))->Projection"
},
{
"SQL": "select a from t where c_str like 'abc%af'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abd\")]->Sel([like(test.t.c_str, abc%af, 92)]))->Projection"
},
{
"SQL": "select a from t where c_str like 'abc\\_' escape ''",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc\\_'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc\\\\_'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc\\_%'",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc`\")])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc=_%' escape '='",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc`\")])->Projection"
},
{
"SQL": "select a from t where c_str like 'abc\\__'",
"Best": "IndexReader(Index(t.c_d_e_str)[(\"abc_\",\"abc`\")]->Sel([like(test.t.c_str, abc\\__, 92)]))->Projection"
},
{
"SQL": "select a from t where c_str like 123",
"Best": "IndexReader(Index(t.c_d_e_str)[[\"123\",\"123\"]])->Projection"
},
{
"SQL": "select a from t where c = 1.9 and d > 3",
"Best": "Dual"
},
{
"SQL": "select a from t where c < 1.1",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,2)])->Projection"
},
{
"SQL": "select a from t where c <= 1.9",
"Best": "IndexReader(Index(t.c_d_e)[[-inf,1]])->Projection"
},
{
"SQL": "select a from t where c >= 1.1",
"Best": "IndexReader(Index(t.c_d_e)[[2,+inf]])->Projection"
},
{
"SQL": "select a from t where c > 1.9",
"Best": "IndexReader(Index(t.c_d_e)[(1,+inf]])->Projection"
},
{
"SQL": "select a from t where c = 123456789098765432101234",
"Best": "Dual"
},
{
"SQL": "select a from t where c = 'hanfei'",
"Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([eq(cast(test.t.c, double BINARY), cast(hanfei, double BINARY))]))->Projection"
}
]
},
{
"Name": "TestAggEliminator",
"Cases": [
{
"SQL": "select max(a) from t;",
"Best": "TableReader(Table(t)->Limit)->Limit->StreamAgg"
},
{
"SQL": "select min(a) from t;",
"Best": "TableReader(Table(t)->Limit)->Limit->StreamAgg"
},
{
"SQL": "select min(c_str) from t;",
"Best": "IndexReader(Index(t.c_d_e_str)[[-inf,+inf]]->Limit)->Limit->StreamAgg"
},
{
"SQL": "select max(a), b from t;",
"Best": "TableReader(Table(t)->StreamAgg)->StreamAgg"
},
{
"SQL": "select max(a+1) from t;",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]]->Sel([not(isnull(plus(test.t.a, 1)))])->TopN([plus(test.t.a, 1) true],0,1))->Projection->TopN([Column#40 true],0,1)->Projection->Projection->StreamAgg"
},
{
"SQL": "select max(a), min(a) from t;",
"Best": "LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}"
},
{
"SQL": "select max(a), min(a) from t where a > 10",
"Best": "LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}"
},
{
"SQL": "select max(d), min(d) from t where c = 1 and d > 10",
"Best": "LeftHashJoin{IndexReader(Index(t.c_d_e)[(1 10,1 +inf]]->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[(1 10,1 +inf]]->Limit)->Limit->StreamAgg}"
},
{
"SQL": "select max(a), max(c), min(f) from t",
"Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit->StreamAgg}->IndexReader(Index(t.f)[[NULL,+inf]]->Limit)->Limit->StreamAgg}"
},
{
"SQL": "select max(a), max(b) from t",
"Best": "TableReader(Table(t)->StreamAgg)->StreamAgg"
},
{
"SQL": "select max(a), max(c) from t where c > 10",
"Best": "IndexReader(Index(t.c_d_e)[(10,+inf]]->StreamAgg)->StreamAgg"
},
{
"SQL": "select max(a), min(a) from t where a * 3 + 10 < 100",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]]->Sel([lt(plus(mul(test.t.a, 3), 10), 100)])->StreamAgg)->StreamAgg"
},
{
"SQL": "select max(a) from t group by b;",
"Best": "TableReader(Table(t)->HashAgg)->HashAgg"
},
{
"SQL": "select max(a) from (select t1.a from t t1 join t t2 on t1.a=t2.a) t",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Limit->StreamAgg"
}
]
},
{
"Name": "TestUnmatchedTableInHint",
"Cases": [
{
"SQL": "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a",
"Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ MERGE_JOIN(t3, t4) */ or /*+ TIDB_SMJ(t3, t4) */. Maybe you can use the table alias name"
},
{
"SQL": "SELECT /*+ TIDB_HJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a",
"Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ HASH_JOIN(t3, t4) */ or /*+ TIDB_HJ(t3, t4) */. Maybe you can use the table alias name"
},
{
"SQL": "SELECT /*+ TIDB_INLJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a",
"Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ INL_JOIN(t3, t4) */ or /*+ TIDB_INLJ(t3, t4) */. Maybe you can use the table alias name"
},
{
"SQL": "SELECT /*+ TIDB_SMJ(t1, t2) */ * from t t1, t t2 where t1.a = t2.a",
"Warning": ""
},
{
"SQL": "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a",
"Warning": "[planner:1815]There are no matching table names for (t4) in optimizer hint /*+ MERGE_JOIN(t3, t4) */ or /*+ TIDB_SMJ(t3, t4) */. Maybe you can use the table alias name"
}
]
},
{
"Name": "TestJoinHints",
"Cases": [
{
"SQL": "select /*+ TIDB_INLJ(t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;",
"Best": "RightHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection",
"Warning": "",
"Hints": "use_index(@`sel_1` `test`.`t3` `f`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` `f`), inl_join(@`sel_1` `test`.`t1`), hash_join(@`sel_1` `test`.`t3`)"
},
{
"SQL": "select /*+ TIDB_INLJ(test.t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;",
"Best": "RightHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection",
"Warning": "",
"Hints": "use_index(@`sel_1` `test`.`t3` `f`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` `f`), inl_join(@`sel_1` `test`.`t1`), hash_join(@`sel_1` `test`.`t3`)"
},
{
"SQL": "select /*+ TIDB_INLJ(t1) */ t1.b, t2.a from t t1, t t2 where t1.b = t2.a;",
"Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.b,test.t.a)",
"Warning": "[planner:1815]Optimizer Hint /*+ INL_JOIN(t1) */ or /*+ TIDB_INLJ(t1) */ is inapplicable",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` `f`), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ TIDB_INLJ(t2) */ t1.b, t2.a from t2 t1, t2 t2 where t1.b=t2.b and t2.c=-1;",
"Best": "IndexJoin{IndexReader(Index(t2.b)[[NULL,+inf]])->TableReader(Table(t2)->Sel([eq(test.t2.c, -1)]))}(test.t2.b,test.t2.b)",
"Warning": "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable",
"Hints": "use_index(@`sel_1` `test`.`t1` `b`), use_index(@`sel_1` `test`.`t2` ), inl_join(@`sel_1` `test`.`t1`)"
}
]
},
{
"Name": "TestAggregationHints",
"Cases": [
{
"SQL": "select count(*) from t t1, t t2 where t1.a = t2.b",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->StreamAgg",
"Warning": ""
},
{
"SQL": "select count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])->Projection}(test.t.a,Column#26)->HashAgg",
"Warning": ""
},
{
"SQL": "select /*+ HASH_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->HashAgg",
"Warning": ""
},
{
"SQL": "select /*+ STREAM_AGG() */ count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])->Projection}(test.t.a,Column#26)->Sort->StreamAgg",
"Warning": ""
},
{
"SQL": "select /*+ HASH_AGG() STREAM_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->StreamAgg",
"Warning": "[planner:1815]Optimizer aggregation hints are conflicted"
},
{
"SQL": "select /*+ STREAM_AGG() */ distinct a from t",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]])",
"Warning": ""
},
{
"SQL": "select /*+ HASH_AGG() */ t1.a from t t1 where t1.a < any(select t2.b from t t2)",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]]->Sel([1]))->TableReader(Table(t)->Sel([1])->HashAgg)->HashAgg->Sel([ne(Column#27, 0) 1])}",
"Warning": ""
},
{
"SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a != any(select t2.b from t t2)",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]]->Sel([1]))->TableReader(Table(t)->Sel([1]))->HashAgg->Sel([ne(Column#28, 0) 1])}",
"Warning": ""
},
{
"SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a = all(select t2.b from t t2)",
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))->HashAgg->Sel([or(and(le(Column#26, 1), if(ne(Column#27, 0), <nil>, 1)), or(eq(Column#28, 0), 0))])}",
"Warning": ""
},
{
"SQL": "select /*+ STREAM_AGG() */ sum(t1.a) from t t1 join t t2 on t1.b = t2.b group by t1.b",
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))->Sort->Projection->StreamAgg}(test.t.b,test.t.b)->HashAgg",
"Warning": ""
},
{
"SQL": "select /*+ STREAM_AGG() */ e, sum(b) from t group by e",
"Best": "TableReader(Table(t))->Sort->Projection->StreamAgg->Projection",
"Warning": ""
}
]
},
{
"Name": "TestQueryBlockHint",
"Cases": [
{
"SQL": "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@sel_2 t3) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)->Projection",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` ), use_index(@`sel_2` `test`.`t3` `c_d_e`), inl_join(@`sel_2` `test`.`t3`), merge_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@qb t3) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)->Projection",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` ), use_index(@`sel_2` `test`.`t3` `c_d_e`), inl_join(@`sel_2` `test`.`t3`), merge_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` ), use_index(@`sel_2` `test`.`t3` `c_d_e`), merge_join(@`sel_2` `test`.`t2`), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` ), use_index(@`sel_2` `test`.`t3` `c_d_e`), merge_join(@`sel_2` `test`.`t2`), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` `f`), use_index(@`sel_2` `test`.`t3` `c_d_e`), hash_join(@`sel_2` `test`.`t2`), inl_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a",
"Plan": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` `f`), use_index(@`sel_2` `test`.`t3` `c_d_e`), hash_join(@`sel_2` `test`.`t2`), inl_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_AGG(@sel_1), STREAM_AGG(@sel_2) */ count(*) from t t1 where t1.a < (select count(*) from t t2 where t1.a > t2.a)",
"Plan": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]]->Sel([gt(test.t.a, test.t.a)])->StreamAgg)->StreamAgg->Sel([not(isnull(Column#25))])}->HashAgg",
"Hints": "use_index(@`sel_1` `test`.`t1` `f`), use_index(@`sel_2` `test`.`t2` `f`), stream_agg(@`sel_2`), hash_agg(@`sel_1`)"
},
{
"SQL": "select /*+ STREAM_AGG(@sel_1), HASH_AGG(@qb) */ count(*) from t t1 where t1.a < (select /*+ QB_NAME(qb) */ count(*) from t t2 where t1.a > t2.a)",
"Plan": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]]->Sel([gt(test.t.a, test.t.a)])->HashAgg)->HashAgg->Sel([not(isnull(Column#25))])}->StreamAgg",
"Hints": "use_index(@`sel_1` `test`.`t1` `f`), use_index(@`sel_2` `test`.`t2` `f`), hash_agg(@`sel_2`), stream_agg(@`sel_1`)"
},
{
"SQL": "select /*+ HASH_AGG(@sel_2) */ a, (select count(*) from t t1 where t1.b > t.a) from t where b > (select b from t t2 where t2.b = t.a limit 1)",
"Plan": "Apply{Apply{TableReader(Table(t))->TableReader(Table(t)->Sel([eq(test.t.b, test.t.a)])->Limit)->Limit}->TableReader(Table(t)->Sel([gt(test.t.b, test.t.a)])->HashAgg)->HashAgg}->Projection",
"Hints": "use_index(@`sel_1` `test`.`t` ), use_index(@`sel_3` `test`.`t2` ), use_index(@`sel_2` `test`.`t1` ), hash_agg(@`sel_2`)"
},
{
"SQL": "select /*+ HASH_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t1) */ t1.b, t2.a, t2.aa from t t1, (select t1.a as a, t2.a as aa from t t1, t t2) t2 where t1.a = t2.aa;",
"Plan": "RightHashJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])}}(test.t.a,test.t.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_2` `test`.`t1` `f`), use_index(@`sel_2` `test`.`t2` `f`), hash_join(@`sel_2` `test`.`t1`), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b",
"Plan": "MergeInnerJoin{LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort->TableReader(Table(t))->Sort}(test.t.b,test.t.b)",
"Hints": "use_index(@`sel_2` `test`.`t1` ), use_index(@`sel_2` `test`.`t2` `f`), hash_join(@`sel_2` `test`.`t1`), use_index(@`sel_1` `test`.`t2` ), merge_join(@`sel_1` `test`.`t1`)"
}
]
},
{
"Name": "TestIndexJoinUnionScan",
"Cases": [
{
"SQL": [
"insert into t values(1, 1)",
"explain select /*+ TIDB_INLJ(t2) */ * from t t1, t t2 where t1.a = t2.a"
],
"Plan": [
"IndexJoin_12 12500.00 root inner join, inner:UnionScan_11, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)",
"├─UnionScan_15(Build) 10000.00 root ",
"│ └─TableReader_17 10000.00 root data:TableFullScan_16",
"│ └─TableFullScan_16 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
"└─UnionScan_11(Probe) 1.00 root ",
" └─TableReader_10 1.00 root data:TableRangeScan_9",
" └─TableRangeScan_9 1.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo"
]
},
{
"SQL": [
"insert into t values(1, 1)",
"explain select /*+ TIDB_INLJ(t2) */ * from t t1, t t2 where t1.a = t2.b"
],
"Plan": [
"HashJoin_15 12487.50 root inner join, equal:[eq(test.t.a, test.t.b)]",
"├─UnionScan_17(Build) 9990.00 root not(isnull(test.t.b))",
"│ └─TableReader_20 9990.00 root data:Selection_19",
"│ └─Selection_19 9990.00 cop[tikv] not(isnull(test.t.b))",
"│ └─TableFullScan_18 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─UnionScan_21(Probe) 10000.00 root ",
" └─TableReader_23 10000.00 root data:TableFullScan_22",
" └─TableFullScan_22 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
]
},
{
"SQL": [
"insert into t values(1, 1)",
"explain select /*+ TIDB_INLJ(t2) */ t1.a , t2.b from t t1, t t2 where t1.a = t2.b"
],
"Plan": [
"HashJoin_15 12487.50 root inner join, equal:[eq(test.t.a, test.t.b)]",
"├─UnionScan_17(Build) 9990.00 root not(isnull(test.t.b))",
"│ └─TableReader_20 9990.00 root data:Selection_19",
"│ └─Selection_19 9990.00 cop[tikv] not(isnull(test.t.b))",
"│ └─TableFullScan_18 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─UnionScan_21(Probe) 10000.00 root ",
" └─TableReader_23 10000.00 root data:TableFullScan_22",
" └─TableFullScan_22 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
]
},
{
"SQL": [
"insert into tt values(1)",
"explain select /*+ TIDB_INLJ(t2) */ * from tt t1, tt t2 where t1.a = t2.a"
],
"Plan": [
"HashJoin_19 25000.00 root inner join, equal:[eq(test.tt.a, test.tt.a)]",
"├─PartitionUnion_28(Build) 20000.00 root ",
"│ ├─UnionScan_29 10000.00 root ",
"│ │ └─TableReader_31 10000.00 root data:TableFullScan_30",
"│ │ └─TableFullScan_30 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo",
"│ └─UnionScan_32 10000.00 root ",
"│ └─TableReader_34 10000.00 root data:TableFullScan_33",
"│ └─TableFullScan_33 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo",
"└─PartitionUnion_21(Probe) 20000.00 root ",
" ├─UnionScan_22 10000.00 root ",
" │ └─TableReader_24 10000.00 root data:TableFullScan_23",
" │ └─TableFullScan_23 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo",
" └─UnionScan_25 10000.00 root ",
" └─TableReader_27 10000.00 root data:TableFullScan_26",
" └─TableFullScan_26 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestSemiJoinToInner",
"Cases": [
{
"SQL": "select t1.a, (select count(t2.a) from t t2 where t2.g in (select t3.d from t t3 where t3.c = t1.a)) as agg_col from t t1;",
"Best": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]]->HashAgg)->HashAgg->IndexReader(Index(t.g)[[NULL,+inf]])}(test.t.d,test.t.g)}->HashAgg"
}
]
},
{
"Name": "TestIndexJoinHint",
"Cases": [
{
"SQL": "select /*+ INL_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;",
"Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)"
},
{
"SQL": "select /*+ INL_HASH_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;",
"Plan": "IndexHashJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)"
},
{
"SQL": "select /*+ INL_MERGE_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;",
"Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)"
},
{
"SQL": "select /*+ inl_merge_join(t2) */ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g",
"Plan": "IndexJoin{IndexReader(Index(t.g_3)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,+inf]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)"
},
{
"SQL": "select /*+inl_merge_join(t2)*/ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g order by t1.a",
"Plan": "IndexJoin{TableReader(Table(t))->IndexReader(Index(t.g_2)[[NULL,+inf]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)"
}
]
},
{
"Name": "TestAggToCopHint",
"Cases": [
{
"SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ sum(a) from ta group by a",
"Best": "IndexReader(Index(ta.a)[[NULL,+inf]]->HashAgg)->HashAgg",
"Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists"
},
{
"SQL": "select /*+ AGG_TO_COP(), USE_INDEX(t) */ sum(b) from ta group by b",
"Best": "TableReader(Table(ta)->HashAgg)->HashAgg",
"Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists"
},
{
"SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ distinct a from ta group by a",
"Best": "IndexReader(Index(ta.a)[[NULL,+inf]]->HashAgg)->HashAgg",
"Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists"
},
{
"SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), HASH_JOIN(t1), USE_INDEX(t1), USE_INDEX(t2) */ sum(t1.a) from ta t1, ta t2 where t1.a = t2.b group by t1.a",
"Best": "LeftHashJoin{TableReader(Table(ta)->Sel([not(isnull(test.ta.a))]))->TableReader(Table(ta)->Sel([not(isnull(test.ta.b))]))}(test.ta.a,test.ta.b)->Projection->HashAgg",
"Warning": "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
}
]
},
{
"Name": "TestLimitToCopHint",
"Cases": [
{
"SQL": "select /*+ LIMIT_TO_COP() */ * from tn where a = 1 and b > 10 and b < 20 and c > 50 order by d limit 1",
"Plan": [
"TopN_8 0.83 root test.tn.d:asc, offset:0, count:1",
"└─IndexReader_15 0.83 root index:TopN_14",
" └─TopN_14 0.83 cop[tikv] test.tn.d:asc, offset:0, count:1",
" └─Selection_13 0.83 cop[tikv] gt(test.tn.c, 50)",
" └─IndexRangeScan_12 2.50 cop[tikv] table:tn, index:a(a, b, c, d) range:(1 10,1 20), keep order:false, stats:pseudo"
],
"Warning": ""
},
{
"SQL": "select * from tn where a = 1 and b > 10 and b < 20 and c > 50 order by d limit 1",
"Plan": [
"TopN_10 0.83 root test.tn.d:asc, offset:0, count:1",
"└─IndexReader_20 0.83 root index:Selection_19",
" └─Selection_19 0.83 cop[tikv] gt(test.tn.c, 50)",
" └─IndexRangeScan_18 2.50 cop[tikv] table:tn, index:a(a, b, c, d) range:(1 10,1 20), keep order:false, stats:pseudo"
],
"Warning": ""
},
{
"SQL": "select /*+ LIMIT_TO_COP() */ a from tn where mod(a, 2) order by a limit 1",
"Plan": [
"Limit_13 1.00 root offset:0, count:1",
"└─Selection_19 1.00 root mod(test.tn.a, 2)",
" └─IndexReader_21 1.00 root index:IndexFullScan_20",
" └─IndexFullScan_20 1.00 cop[tikv] table:tn, index:a(a, b, c, d) keep order:true, stats:pseudo"
],
"Warning": "[planner:1815]Optimizer Hint LIMIT_TO_COP is inapplicable"
}
]
},
{
"Name": "TestPushdownDistinctEnable",
"Cases": [
{
"SQL": "select /*+ HASH_AGG() */ avg(distinct a) from t;",
"Plan": [
"HashAgg_8 1.00 root funcs:avg(distinct Column#6)->Column#5",
"└─Projection_10 1.00 root cast(test.t.a, decimal(65,4) BINARY)->Column#6",
" └─TableReader_9 1.00 root data:HashAgg_5",
" └─HashAgg_5 1.00 cop[tikv] group by:test.t.a, ",
" └─TableFullScan_7 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1.5000"
]
},
{
"SQL": "select /*+ HASH_AGG() */ a, count(distinct a) from t;",
"Plan": [
"Projection_4 1.00 root test.t.a, Column#5",
"└─HashAgg_8 1.00 root funcs:count(distinct test.t.a)->Column#5, funcs:firstrow(Column#6)->test.t.a",
" └─TableReader_9 1.00 root data:HashAgg_5",
" └─HashAgg_5 1.00 cop[tikv] group by:test.t.a, funcs:firstrow(test.t.a)->Column#6",
" └─TableFullScan_7 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1 2"
]
},
{
"SQL": "select /*+ HASH_AGG() */ avg(b), c, avg(b), count(distinct A, B), count(distinct A), count(distinct c), sum(b) from t group by c;",
"Plan": [
"Projection_4 8000.00 root Column#5, test.t.c, Column#5, Column#6, Column#7, Column#8, Column#9",
"└─HashAgg_8 8000.00 root group by:test.t.c, funcs:avg(Column#10, Column#11)->Column#5, funcs:count(distinct test.t.a, test.t.b)->Column#6, funcs:count(distinct test.t.a)->Column#7, funcs:count(distinct test.t.c)->Column#8, funcs:sum(Column#12)->Column#9, funcs:firstrow(test.t.c)->test.t.c",
" └─TableReader_9 8000.00 root data:HashAgg_5",
" └─HashAgg_5 8000.00 cop[tikv] group by:test.t.a, test.t.b, test.t.c, funcs:count(test.t.b)->Column#10, funcs:sum(test.t.b)->Column#11, funcs:sum(test.t.b)->Column#12",
" └─TableFullScan_7 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1.0000 1 1.0000 1 1 1 1",
"1.3333 3 1.3333 3 2 1 4",
"2.0000 <nil> 2.0000 1 1 0 2"
]
},
{
"SQL": "select /*+ STREAM_AGG() */ count(distinct c) from t group by c;",
"Plan": [
"StreamAgg_11 8000.00 root group by:test.t.c, funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_12 8000.00 root index:StreamAgg_7",
" └─StreamAgg_7 8000.00 cop[tikv] group by:test.t.c, ",
" └─IndexFullScan_10 10000.00 cop[tikv] table:t, index:c(c) keep order:true, stats:pseudo"
],
"Result": [
"0",
"1",
"1"
]
},
{
"SQL": "select /*+ STREAM_AGG() */ count(distinct c) from t;",
"Plan": [
"StreamAgg_7 1.00 root funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_11 10000.00 root index:IndexFullScan_10",
" └─IndexFullScan_10 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"2"
]
},
{
"SQL": "select /*+ HASH_AGG() */ count(distinct c) from t;",
"Plan": [
"HashAgg_9 1.00 root funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_10 1.00 root index:HashAgg_5",
" └─HashAgg_5 1.00 cop[tikv] group by:test.t.c, ",
" └─IndexFullScan_8 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"2"
]
},
{
"SQL": "select count(distinct c) from t group by c;",
"Plan": [
"HashAgg_10 8000.00 root group by:test.t.c, funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_11 8000.00 root index:HashAgg_5",
" └─HashAgg_5 8000.00 cop[tikv] group by:test.t.c, ",
" └─IndexFullScan_9 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"0",
"1",
"1"
]
},
{
"SQL": "select count(distinct c) from t;",
"Plan": [
"HashAgg_9 1.00 root funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_10 1.00 root index:HashAgg_5",
" └─HashAgg_5 1.00 cop[tikv] group by:test.t.c, ",
" └─IndexFullScan_8 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"2"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ sum(distinct b) from pt;",
"Plan": [
"HashAgg_11 1.00 root funcs:sum(distinct Column#9)->Column#4",
"└─Projection_23 16000.00 root cast(test.pt.b, decimal(65,0) BINARY)->Column#9",
" └─PartitionUnion_12 16000.00 root ",
" ├─HashAgg_16 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" │ └─TableReader_17 8000.00 root data:HashAgg_13",
" │ └─HashAgg_13 8000.00 cop[tikv] group by:test.pt.b, ",
" │ └─TableFullScan_15 10000.00 cop[tikv] table:pt, partition:p0 keep order:false, stats:pseudo",
" └─HashAgg_21 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" └─TableReader_22 8000.00 root data:HashAgg_18",
" └─HashAgg_18 8000.00 cop[tikv] group by:test.pt.b, ",
" └─TableFullScan_20 10000.00 cop[tikv] table:pt, partition:p1 keep order:false, stats:pseudo"
],
"Result": [
"<nil>"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ count(distinct a) from (select * from ta union all select * from tb) t;",
"Plan": [
"HashAgg_14 1.00 root funcs:count(distinct Column#5)->Column#6",
"└─Union_15 16000.00 root ",
" ├─HashAgg_19 8000.00 root group by:test.ta.a, funcs:firstrow(test.ta.a)->Column#5, funcs:firstrow(test.ta.a)->Column#5",
" │ └─TableReader_20 8000.00 root data:HashAgg_16",
" │ └─HashAgg_16 8000.00 cop[tikv] group by:test.ta.a, ",
" │ └─TableFullScan_18 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo",
" └─HashAgg_24 8000.00 root group by:test.tb.a, funcs:firstrow(test.tb.a)->Column#5, funcs:firstrow(test.tb.a)->Column#5",
" └─TableReader_25 8000.00 root data:HashAgg_21",
" └─HashAgg_21 8000.00 cop[tikv] group by:test.tb.a, ",
" └─TableFullScan_23 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo"
],
"Result": [
"1"
]
}
]
},
{
"Name": "TestPushdownDistinctDisable",
"Cases": [
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ avg(distinct a) from t;",
"Plan": [
"HashAgg_5 1.00 root funcs:avg(distinct Column#6)->Column#5",
"└─Projection_8 10000.00 root cast(test.t.a, decimal(65,4) BINARY)->Column#6",
" └─TableReader_7 10000.00 root data:TableFullScan_6",
" └─TableFullScan_6 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1.5000"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ a, count(distinct a) from t;",
"Plan": [
"Projection_4 1.00 root test.t.a, Column#5",
"└─HashAgg_5 1.00 root funcs:count(distinct test.t.a)->Column#5, funcs:firstrow(test.t.a)->test.t.a",
" └─TableReader_7 10000.00 root data:TableFullScan_6",
" └─TableFullScan_6 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1 2"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ avg(b), c, avg(b), count(distinct A, B), count(distinct A), count(distinct c), sum(b) from t group by c;",
"Plan": [
"Projection_4 8000.00 root Column#5, test.t.c, Column#5, Column#6, Column#7, Column#8, Column#9",
"└─HashAgg_5 8000.00 root group by:Column#17, funcs:avg(Column#10)->Column#5, funcs:count(distinct Column#11, Column#12)->Column#6, funcs:count(distinct Column#13)->Column#7, funcs:count(distinct Column#14)->Column#8, funcs:sum(Column#15)->Column#9, funcs:firstrow(Column#16)->test.t.c",
" └─Projection_8 10000.00 root cast(test.t.b, decimal(65,4) BINARY)->Column#10, test.t.a, test.t.b, test.t.a, test.t.c, cast(test.t.b, decimal(65,0) BINARY)->Column#15, test.t.c, test.t.c",
" └─TableReader_7 10000.00 root data:TableFullScan_6",
" └─TableFullScan_6 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Result": [
"1.0000 1 1.0000 1 1 1 1",
"1.3333 3 1.3333 3 2 1 4",
"2.0000 <nil> 2.0000 1 1 0 2"
]
},
{
"SQL": "select /*+ STREAM_AGG(), AGG_TO_COP() */ count(distinct c) from t group by c;",
"Plan": [
"StreamAgg_6 8000.00 root group by:test.t.c, funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_9 10000.00 root index:IndexFullScan_8",
" └─IndexFullScan_8 10000.00 cop[tikv] table:t, index:c(c) keep order:true, stats:pseudo"
],
"Result": [
"0",
"1",
"1"
]
},
{
"SQL": "select /*+ STREAM_AGG(), AGG_TO_COP() */ count(distinct c) from t;",
"Plan": [
"StreamAgg_6 1.00 root funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_11 10000.00 root index:IndexFullScan_10",
" └─IndexFullScan_10 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"2"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ count(distinct c) from t;",
"Plan": [
"HashAgg_5 1.00 root funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_9 10000.00 root index:IndexFullScan_8",
" └─IndexFullScan_8 10000.00 cop[tikv] table:t, index:c(c) keep order:false, stats:pseudo"
],
"Result": [
"2"
]
},
{
"SQL": "select /*+ AGG_TO_COP() */ count(distinct c) from t group by c;",
"Plan": [
"StreamAgg_6 8000.00 root group by:test.t.c, funcs:count(distinct test.t.c)->Column#5",
"└─IndexReader_12 10000.00 root index:IndexFullScan_11",
" └─IndexFullScan_11 10000.00 cop[tikv] table:t, index:c(c) keep order:true, stats:pseudo"
],
"Result": [
"0",
"1",
"1"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ sum(distinct b) from pt;",
"Plan": [
"HashAgg_11 1.00 root funcs:sum(distinct Column#9)->Column#4",
"└─Projection_23 16000.00 root cast(test.pt.b, decimal(65,0) BINARY)->Column#9",
" └─PartitionUnion_12 16000.00 root ",
" ├─HashAgg_16 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" │ └─TableReader_17 8000.00 root data:HashAgg_13",
" │ └─HashAgg_13 8000.00 cop[tikv] group by:test.pt.b, ",
" │ └─TableFullScan_15 10000.00 cop[tikv] table:pt, partition:p0 keep order:false, stats:pseudo",
" └─HashAgg_21 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" └─TableReader_22 8000.00 root data:HashAgg_18",
" └─HashAgg_18 8000.00 cop[tikv] group by:test.pt.b, ",
" └─TableFullScan_20 10000.00 cop[tikv] table:pt, partition:p1 keep order:false, stats:pseudo"
],
"Result": [
"<nil>"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ count(distinct a) from (select * from ta union all select * from tb) t;",
"Plan": [
"HashAgg_14 1.00 root funcs:count(distinct Column#5)->Column#6",
"└─Union_15 16000.00 root ",
" ├─HashAgg_19 8000.00 root group by:test.ta.a, funcs:firstrow(test.ta.a)->Column#5, funcs:firstrow(test.ta.a)->Column#5",
" │ └─TableReader_20 8000.00 root data:HashAgg_16",
" │ └─HashAgg_16 8000.00 cop[tikv] group by:test.ta.a, ",
" │ └─TableFullScan_18 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo",
" └─HashAgg_24 8000.00 root group by:test.tb.a, funcs:firstrow(test.tb.a)->Column#5, funcs:firstrow(test.tb.a)->Column#5",
" └─TableReader_25 8000.00 root data:HashAgg_21",
" └─HashAgg_21 8000.00 cop[tikv] group by:test.tb.a, ",
" └─TableFullScan_23 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo"
],
"Result": [
"1"
]
}
]
},
{
"Name": "TestPushdownDistinctEnableAggPushDownDisable",
"Cases": [
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ sum(distinct b) from pt;",
"Plan": [
"HashAgg_11 1.00 root funcs:sum(distinct Column#9)->Column#4",
"└─Projection_23 16000.00 root cast(test.pt.b, decimal(65,0) BINARY)->Column#9",
" └─PartitionUnion_12 16000.00 root ",
" ├─HashAgg_16 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" │ └─TableReader_17 8000.00 root data:HashAgg_13",
" │ └─HashAgg_13 8000.00 cop[tikv] group by:test.pt.b, ",
" │ └─TableFullScan_15 10000.00 cop[tikv] table:pt, partition:p0 keep order:false, stats:pseudo",
" └─HashAgg_21 8000.00 root group by:test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b, funcs:firstrow(test.pt.b)->test.pt.b",
" └─TableReader_22 8000.00 root data:HashAgg_18",
" └─HashAgg_18 8000.00 cop[tikv] group by:test.pt.b, ",
" └─TableFullScan_20 10000.00 cop[tikv] table:pt, partition:p1 keep order:false, stats:pseudo"
],
"Result": [
"<nil>"
]
},
{
"SQL": "select /*+ HASH_AGG(), AGG_TO_COP() */ count(distinct a) from (select * from ta union all select * from tb) t;",
"Plan": [
"HashAgg_11 1.00 root funcs:count(distinct Column#5)->Column#6",
"└─Union_12 20000.00 root ",
" ├─TableReader_15 10000.00 root data:TableFullScan_14",
" │ └─TableFullScan_14 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo",
" └─TableReader_18 10000.00 root data:TableFullScan_17",
" └─TableFullScan_17 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo"
],
"Result": [
"1"
]
}
]
},
{
"Name": "TestGroupConcatOrderby",
"Cases": [
{
"SQL": "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from test;",
"Plan": [
"HashAgg_5 1.00 root funcs:group_concat(Column#6 order by Column#7 desc separator \"++\")->Column#4, funcs:group_concat(Column#8 order by Column#9 desc, Column#10 asc separator \"--\")->Column#5",
"└─Projection_18 10000.00 root cast(test.test.name, var_string(20))->Column#6, test.test.name, cast(test.test.id, var_string(20))->Column#8, test.test.name, test.test.id",
" └─TableReader_11 10000.00 root data:TableFullScan_10",
" └─TableFullScan_10 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Result": [
"500++200++30++20++20++10 3--3--1--1--2--1"
]
},
{
"SQL": "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from ptest;",
"Plan": [
"HashAgg_10 1.00 root funcs:group_concat(Column#6 order by Column#7 desc separator \"++\")->Column#4, funcs:group_concat(Column#8 order by Column#9 desc, Column#10 asc separator \"--\")->Column#5",
"└─Projection_23 20000.00 root cast(test.ptest.name, var_string(20))->Column#6, test.ptest.name, cast(test.ptest.id, var_string(20))->Column#8, test.ptest.name, test.ptest.id",
" └─PartitionUnion_13 20000.00 root ",
" ├─TableReader_15 10000.00 root data:TableFullScan_14",
" │ └─TableFullScan_14 10000.00 cop[tikv] table:ptest, partition:p0 keep order:false, stats:pseudo",
" └─TableReader_17 10000.00 root data:TableFullScan_16",
" └─TableFullScan_16 10000.00 cop[tikv] table:ptest, partition:p1 keep order:false, stats:pseudo"
],
"Result": [
"500++200++30++20++20++10 3--3--1--1--2--1"
]
},
{
"SQL": "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from test;",
"Plan": [
"HashAgg_5 1.00 root funcs:group_concat(distinct Column#5 order by Column#6 desc separator \",\")->Column#4",
"└─Projection_9 10000.00 root cast(test.test.name, var_string(20))->Column#5, test.test.name",
" └─TableReader_8 10000.00 root data:TableFullScan_7",
" └─TableFullScan_7 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Result": [
"500,200,30,20,10"
]
},
{
"SQL": "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from ptest;",
"Plan": [
"StreamAgg_9 1.00 root funcs:group_concat(distinct Column#5 order by Column#6 desc separator \",\")->Column#4",
"└─Projection_20 20000.00 root cast(test.ptest.name, var_string(20))->Column#5, test.ptest.name",
" └─PartitionUnion_15 20000.00 root ",
" ├─TableReader_17 10000.00 root data:TableFullScan_16",
" │ └─TableFullScan_16 10000.00 cop[tikv] table:ptest, partition:p0 keep order:false, stats:pseudo",
" └─TableReader_19 10000.00 root data:TableFullScan_18",
" └─TableFullScan_18 10000.00 cop[tikv] table:ptest, partition:p1 keep order:false, stats:pseudo"
],
"Result": [
"500,200,30,20,10"
]
}
]
},
{
"Name": "TestDAGPlanBuilderWindow",
"Cases": [
{
"SQL": "select lead(a, 1) over (partition by null) as c from t",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]])->Window(lead(test.t.a, 1)->Column#14 over())->Projection"
}
]
},
{
"Name": "TestDAGPlanBuilderWindowParallel",
"Cases": [
{
"SQL": "select lead(a, 1) over (partition by null) as c from t",
"Best": "IndexReader(Index(t.f)[[NULL,+inf]])->Window(lead(test.t.a, 1)->Column#14 over())->Projection"
},
{
"SQL": "select lead(a, 1) over (partition by b) as c from t",
"Best": "TableReader(Table(t))->Sort->Window(lead(test.t.a, 1)->Column#14 over(partition by test.t.b))->Partition(execution info: concurrency:4, data source:TableReader_10)->Projection"
}
]
},
{
"Name": "TestNominalSort",
"Cases": [
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a",
"Plan": [
"Projection_20 12487.50 root test.t.a",
"└─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_15(Build) 9990.00 root index:IndexFullScan_14",
" │ └─IndexFullScan_14 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_13(Probe) 9990.00 root index:IndexFullScan_12",
" └─IndexFullScan_12 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a+1",
"Plan": [
"Projection_24 12487.50 root test.t.a",
"└─Projection_23 12487.50 root test.t.a, plus(test.t.a, 1)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_15(Build) 9990.00 root index:IndexFullScan_14",
" │ └─IndexFullScan_14 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_13(Probe) 9990.00 root index:IndexFullScan_12",
" └─IndexFullScan_12 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a-1",
"Plan": [
"Projection_24 12487.50 root test.t.a",
"└─Projection_23 12487.50 root test.t.a, minus(test.t.a, 1)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_15(Build) 9990.00 root index:IndexFullScan_14",
" │ └─IndexFullScan_14 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_13(Probe) 9990.00 root index:IndexFullScan_12",
" └─IndexFullScan_12 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by -t1.a",
"Plan": [
"Projection_32 12487.50 root test.t.a",
"└─Projection_31 12487.50 root test.t.a, unaryminus(test.t.a)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_26(Build) 9990.00 root index:IndexFullScan_25",
" │ └─IndexFullScan_25 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, desc, stats:pseudo",
" └─IndexReader_24(Probe) 9990.00 root index:IndexFullScan_23",
" └─IndexFullScan_23 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, desc, stats:pseudo"
],
"Result": [
"2",
"1",
"1"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by -t1.a+3",
"Plan": [
"Projection_32 12487.50 root test.t.a",
"└─Projection_31 12487.50 root test.t.a, plus(unaryminus(test.t.a), 3)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_26(Build) 9990.00 root index:IndexFullScan_25",
" │ └─IndexFullScan_25 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, desc, stats:pseudo",
" └─IndexReader_24(Probe) 9990.00 root index:IndexFullScan_23",
" └─IndexFullScan_23 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, desc, stats:pseudo"
],
"Result": [
"2",
"1",
"1"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1+t1.a",
"Plan": [
"Projection_24 12487.50 root test.t.a",
"└─Projection_23 12487.50 root test.t.a, plus(1, test.t.a)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_15(Build) 9990.00 root index:IndexFullScan_14",
" │ └─IndexFullScan_14 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_13(Probe) 9990.00 root index:IndexFullScan_12",
" └─IndexFullScan_12 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1-t1.a",
"Plan": [
"Projection_32 12487.50 root test.t.a",
"└─Projection_31 12487.50 root test.t.a, minus(1, test.t.a)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_26(Build) 9990.00 root index:IndexFullScan_25",
" │ └─IndexFullScan_25 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, desc, stats:pseudo",
" └─IndexReader_24(Probe) 9990.00 root index:IndexFullScan_23",
" └─IndexFullScan_23 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, desc, stats:pseudo"
],
"Result": [
"2",
"1",
"1"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1-t1.a+3",
"Plan": [
"Projection_32 12487.50 root test.t.a",
"└─Projection_31 12487.50 root test.t.a, plus(minus(1, test.t.a), 3)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_26(Build) 9990.00 root index:IndexFullScan_25",
" │ └─IndexFullScan_25 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, desc, stats:pseudo",
" └─IndexReader_24(Probe) 9990.00 root index:IndexFullScan_23",
" └─IndexFullScan_23 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, desc, stats:pseudo"
],
"Result": [
"2",
"1",
"1"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1+t1.a+3",
"Plan": [
"Projection_24 12487.50 root test.t.a",
"└─Projection_23 12487.50 root test.t.a, plus(plus(1, test.t.a), 3)->Column#7",
" └─Projection_20 12487.50 root test.t.a",
" └─MergeJoin_21 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_15(Build) 9990.00 root index:IndexFullScan_14",
" │ └─IndexFullScan_14 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_13(Probe) 9990.00 root index:IndexFullScan_12",
" └─IndexFullScan_12 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
},
{
"SQL": "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 3*t1.a",
"Plan": [
"Projection_19 12487.50 root test.t.a",
"└─Sort_7 12487.50 root Column#7:asc",
" └─Projection_20 12487.50 root test.t.a, mul(3, test.t.a)->Column#7",
" └─Projection_8 12487.50 root test.t.a",
" └─MergeJoin_9 12487.50 root inner join, left key:test.t.a, right key:test.t.b",
" ├─IndexReader_14(Build) 9990.00 root index:IndexFullScan_13",
" │ └─IndexFullScan_13 9990.00 cop[tikv] table:t2, index:idx_b(b) keep order:true, stats:pseudo",
" └─IndexReader_12(Probe) 9990.00 root index:IndexFullScan_11",
" └─IndexFullScan_11 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo"
],
"Result": [
"1",
"1",
"2"
]
}
]
},
{
"Name": "TestInlineProjection",
"Cases": [
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1, t2 where t1.a = t2.a;",
"Plan": "LeftHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;",
"Plan": "LeftHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 left outer join t2 on t1.a = t2.a;",
"Plan": "LeftHashJoin{TableReader(Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 right outer join t2 on t1.a = t2.a;",
"Plan": "RightHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2))}(test.t1.a,test.t2.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a in (select t2.a from t2) from t1) x;",
"Plan": "LeftHashJoin{IndexReader(Index(t1.idx_a)[[NULL,+inf]])->IndexReader(Index(t2.idx_a)[[NULL,+inf]])}->Projection",
"Hints": "use_index(@`sel_2` `test`.`t1` `idx_a`), use_index(@`sel_3` `test`.`t2` `idx_a`), hash_join(@`sel_2` `test`.`t1`)"
},
{
"SQL": "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a not in (select t2.a from t2) from t1) x;",
"Plan": "LeftHashJoin{IndexReader(Index(t1.idx_a)[[NULL,+inf]])->IndexReader(Index(t2.idx_a)[[NULL,+inf]])}->Projection",
"Hints": "use_index(@`sel_2` `test`.`t1` `idx_a`), use_index(@`sel_3` `test`.`t2` `idx_a`), hash_join(@`sel_2` `test`.`t1`)"
},
{
"SQL": "select /*+ INL_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;",
"Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` ), inl_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ INL_HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;",
"Plan": "IndexHashJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` ), inl_hash_join(@`sel_1` `test`.`t1`)"
},
{
"SQL": "select /*+ INL_MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;",
"Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)",
"Hints": "use_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` ), inl_join(@`sel_1` `test`.`t1`)"
}
]
},
{
"Name": "TestHintFromDiffDatabase",
"Cases": [
{
"SQL": "select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a",
"Plan": "IndexHashJoin{IndexReader(Index(t2.idx_a)[[-inf,+inf]])->IndexReader(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]))}(test.t2.a,test.t1.a)"
}
]
}
]