From 1209e7f67c0dbaca2926b3d5edf153b40e811794 Mon Sep 17 00:00:00 2001 From: TotaJ Date: Tue, 31 Aug 2021 10:39:18 +0800 Subject: [PATCH] Fix bypass+sort havn't record sort stat to unique sql bug. --- src/common/backend/utils/sort/tuplesort.cpp | 3 +- .../unique_sql/instr_unique_sql.cpp | 3 +- src/gausskernel/runtime/executor/opfusion.cpp | 6 +- .../regress/expected/get_instr_unique_sql.out | 97 +++++++++++++++++++ src/test/regress/parallel_schedule0 | 1 + src/test/regress/sql/get_instr_unique_sql.sql | 24 +++++ 6 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 src/test/regress/expected/get_instr_unique_sql.out create mode 100644 src/test/regress/sql/get_instr_unique_sql.sql diff --git a/src/common/backend/utils/sort/tuplesort.cpp b/src/common/backend/utils/sort/tuplesort.cpp index 38f590aba..764c4d2d9 100644 --- a/src/common/backend/utils/sort/tuplesort.cpp +++ b/src/common/backend/utils/sort/tuplesort.cpp @@ -4262,7 +4262,8 @@ int64 tuplesort_get_peak_memory(Tuplesortstate* state) */ void UpdateUniqueSQLSortStats(Tuplesortstate* state, TimestampTz* start_time) { - if (!is_unique_sql_enabled()) { + /* isUniqueSQLContextInvalid happens when the query is explain xxx */ + if (!is_unique_sql_enabled() || isUniqueSQLContextInvalid()) { return; } unique_sql_sorthash_instr* instr = u_sess->unique_sql_cxt.unique_sql_sort_instr; diff --git a/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp b/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp index e3169a6cf..58df37760 100644 --- a/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp +++ b/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp @@ -442,7 +442,8 @@ static void UpdateUniqueSQLSortHashInfo(UniqueSQL* unique_sql) */ void UpdateUniqueSQLHashStats(HashJoinTable hashtable, TimestampTz* start_time) { - if (!is_unique_sql_enabled()) { + /* isUniqueSQLContextInvalid happens when the query is explain xxx */ + if (!is_unique_sql_enabled() || isUniqueSQLContextInvalid()) { return; } diff --git a/src/gausskernel/runtime/executor/opfusion.cpp b/src/gausskernel/runtime/executor/opfusion.cpp index be8b8cd99..47d2635da 100644 --- a/src/gausskernel/runtime/executor/opfusion.cpp +++ b/src/gausskernel/runtime/executor/opfusion.cpp @@ -3029,7 +3029,7 @@ bool SortFusion::execute(long max_rows, char *completionTag) { max_rows = FETCH_ALL; bool success = false; - + TimestampTz startTime = 0; TupleTableSlot *reslot = m_local.m_reslot; Datum *values = m_local.m_values; bool *isnull = m_local.m_isnull; @@ -3037,6 +3037,7 @@ bool SortFusion::execute(long max_rows, char *completionTag) isnull[i] = true; } + UpdateUniqueSQLSortStats(NULL, &startTime); /* prepare */ m_local.m_scan->refreshParameter(m_local.m_outParams == NULL ? m_local.m_params : m_local.m_outParams); @@ -3075,6 +3076,9 @@ bool SortFusion::execute(long max_rows, char *completionTag) /* sort all data */ tuplesort_performsort(tuplesortstate); + /* analyze the tuplesortstate information for update unique sql sort info */ + UpdateUniqueSQLSortStats(tuplesortstate, &startTime); + /* send sorted data to client */ slot = MakeSingleTupleTableSlot(m_c_local.m_scanDesc); while (tuplesort_gettupleslot(tuplesortstate, true, slot, NULL)) { diff --git a/src/test/regress/expected/get_instr_unique_sql.out b/src/test/regress/expected/get_instr_unique_sql.out new file mode 100644 index 000000000..15dc7e5cb --- /dev/null +++ b/src/test/regress/expected/get_instr_unique_sql.out @@ -0,0 +1,97 @@ +drop table if exists unique_sql_test1; +NOTICE: table "unique_sql_test1" does not exist, skipping +drop table if exists unique_sql_test2; +NOTICE: table "unique_sql_test2" does not exist, skipping +create table unique_sql_test1(a int, b int); +create table unique_sql_test2(a int, b int); +insert into unique_sql_test1 select GENERATE_SERIES(0, 15000),GENERATE_SERIES(0, 15000); +insert into unique_sql_test2 select GENERATE_SERIES(0, 15000),GENERATE_SERIES(0, 15000); +select reset_unique_sql('global','ALL',0); + reset_unique_sql +------------------ + t +(1 row) + +--explain sql won't record unique sql info +explain performance select * from unique_sql_test1 where b in (select b from unique_sql_test2) and a = 66 order by b; +--?.* +--?.* +--? Sort.* + Output: unique_sql_test1.a, unique_sql_test1.b + Sort Key: unique_sql_test1.b +--? Sort Method: quicksort Memory: .* +--? (Buffers: .*) +--?.* +--? -> Hash Join (.*) + Output: unique_sql_test1.a, unique_sql_test1.b + Hash Cond: (unique_sql_test1.b = unique_sql_test2.b) +--? (Buffers: .*) +--? (CPU: .*) +--? -> Seq Scan on public.unique_sql_test1 (cost=.*) + Output: unique_sql_test1.a, unique_sql_test1.b + Filter: (unique_sql_test1.a = 66) +--? Rows Removed by Filter: .* +--? (Buffers: .*) +--? (CPU: .*) +--? -> Hash (cost=.*) + Output: unique_sql_test2.b +--? Buckets: .* +--? (Buffers: .*) +--? (CPU: .*) +--? -> HashAggregate (cost=.*) + Output: unique_sql_test2.b + Group By Key: unique_sql_test2.b +--? (Buffers: .*) +--? (CPU: ex .*) +--? -> Seq Scan on public.unique_sql_test2 (cost=.*) + Output: unique_sql_test2.b +--? (Buffers: .*) +--? (CPU: .*) +--? Total runtime: .* +(32 rows) + +select * from unique_sql_test1 where b in (select b from unique_sql_test2) and a = 66 order by b; + a | b +----+---- + 66 | 66 +(1 row) + +select sort_count,hash_count from get_instr_unique_sql() where query like '%select * from unique_sql_test1 where b in (select b from unique_sql_test2%'; + sort_count | hash_count +------------+------------ + 1 | 1 +(1 row) + +--test sort with sqlbypass +create index i_unique_sql_test1 on unique_sql_test1(a); +create index i_unique_sql_test2 on unique_sql_test2(a); +set enable_beta_opfusion = on; +set enable_bitmapscan = off; +select reset_unique_sql('global','ALL',0); + reset_unique_sql +------------------ + t +(1 row) + +explain (costs off) select * from unique_sql_test1 where a = 66 order by b; + QUERY PLAN +--------------------------------------------------------------- + [Bypass] + Sort + Sort Key: b + -> Index Scan using i_unique_sql_test1 on unique_sql_test1 + Index Cond: (a = 66) +(5 rows) + +select * from unique_sql_test1 where a = 66 order by b; + a | b +----+---- + 66 | 66 +(1 row) + +select sort_count,hash_count from get_instr_unique_sql() where query like '%select * from unique_sql_test1 where%'; + sort_count | hash_count +------------+------------ + 1 | 0 +(1 row) + diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 4ec48186c..fa53b47f7 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -10,6 +10,7 @@ test: single_node_ddl test: single_node_sqlbypass test: median test: array_funcs first_last_agg +test: get_instr_unique_sql # run tablespace by itself, and first, because it forces a checkpoint; # we'd prefer not to have checkpoints later in the tests because that diff --git a/src/test/regress/sql/get_instr_unique_sql.sql b/src/test/regress/sql/get_instr_unique_sql.sql new file mode 100644 index 000000000..d733a84e1 --- /dev/null +++ b/src/test/regress/sql/get_instr_unique_sql.sql @@ -0,0 +1,24 @@ +drop table if exists unique_sql_test1; +drop table if exists unique_sql_test2; +create table unique_sql_test1(a int, b int); +create table unique_sql_test2(a int, b int); +insert into unique_sql_test1 select GENERATE_SERIES(0, 15000),GENERATE_SERIES(0, 15000); +insert into unique_sql_test2 select GENERATE_SERIES(0, 15000),GENERATE_SERIES(0, 15000); +select reset_unique_sql('global','ALL',0); + +--explain sql won't record unique sql info +explain performance select * from unique_sql_test1 where b in (select b from unique_sql_test2) and a = 66 order by b; +select * from unique_sql_test1 where b in (select b from unique_sql_test2) and a = 66 order by b; +select sort_count,hash_count from get_instr_unique_sql() where query like '%select * from unique_sql_test1 where b in (select b from unique_sql_test2%'; + +--test sort with sqlbypass +create index i_unique_sql_test1 on unique_sql_test1(a); +create index i_unique_sql_test2 on unique_sql_test2(a); +set enable_beta_opfusion = on; +set enable_bitmapscan = off; +select reset_unique_sql('global','ALL',0); + +explain (costs off) select * from unique_sql_test1 where a = 66 order by b; +select * from unique_sql_test1 where a = 66 order by b; + +select sort_count,hash_count from get_instr_unique_sql() where query like '%select * from unique_sql_test1 where%'; \ No newline at end of file