Skip to content

Commit

Permalink
Bug #30473261: CONVERT THE INDEX SUBQUERY ENGINES INTO USING THE ITER…
Browse files Browse the repository at this point in the history
…ATOR EXECUTOR [patch 6/10, ha_records]

Don't call ha_records() if we just want to know whether the materialized table
is empty or not.

ha_records() will count all records, which can be fairly expensive and
potentially fire up multiple threads etc.. Instead, start a simple scan,
see whether we can read out at least one row, and then end.

Change-Id: If5f20ba8a6478a928a150691154b5d103a7eb079
  • Loading branch information
Steinar H. Gunderson committed Dec 20, 2019
1 parent 0b45e96 commit 6226c1a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 14 deletions.
27 changes: 14 additions & 13 deletions sql/item_subselect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3298,7 +3298,6 @@ bool subselect_hash_sj_engine::exec(THD *thd) {
the subquery predicate.
*/
if (!is_materialized) {
SELECT_LEX *save_select = thd->lex->current_select();
thd->lex->set_current_select(materialize_engine->single_select_lex());
DBUG_ASSERT(
materialize_engine->single_select_lex()->master_unit()->is_optimized());
Expand All @@ -3320,27 +3319,29 @@ bool subselect_hash_sj_engine::exec(THD *thd) {
*/
is_materialized = true;

// Calculate row count:
// See if we have zero rows or not.
table->file->info(HA_STATUS_VARIABLE);

if (!(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)) {
// index must be closed before ha_records() is called
if (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) {
has_zero_rows = (table->file->stats.records == 0);
} else {
// Index must be closed before starting to scan.
if (table->file->inited) table->file->ha_index_or_rnd_end();
ha_rows num_rows = 0;
table->file->ha_records(&num_rows);
table->file->stats.records = num_rows;
error = thd->is_error();

TableScanIterator scan(thd, table, /*qep_tab=*/nullptr,
/*examined_rows=*/nullptr);
int ret = scan.Read();
if (ret == 1 || thd->is_error()) {
return true;
}
has_zero_rows = (ret == -1);
}

/* Set tmp_param only if its usable, i.e. there are Copy_field's. */
tmp_param = &(item_in->unit->outer_select()->join->tmp_table_param);
if (tmp_param && tmp_param->copy_fields.empty()) tmp_param = nullptr;

thd->lex->set_current_select(save_select);
if (error) return error;
} // if (!is_materialized)

if (table->file->stats.records == 0) {
if (has_zero_rows) {
// The correct answer is FALSE.
item_in->value = false;
return false;
Expand Down
5 changes: 4 additions & 1 deletion sql/item_subselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -849,8 +849,11 @@ inline bool Item_subselect::is_uncacheable() const {

class subselect_hash_sj_engine final : public subselect_indexsubquery_engine {
private:
/* TRUE if the subquery was materialized into a temp table. */
/* true if the subquery was materialized into a temp table. */
bool is_materialized;
// true if we know for sure that there are zero rows in the table.
// Set only after is_materialized is true.
bool has_zero_rows = false;
/**
Existence of inner NULLs in materialized table:
By design, other values than IRRELEVANT_OR_FALSE are possible only if the
Expand Down

0 comments on commit 6226c1a

Please sign in to comment.