[ { "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), , 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 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": [ "" ] }, { "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 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": [ "" ] }, { "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": [ "" ] }, { "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)" } ] } ]