YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/* Analyzeouterjoindependencies,and,ifpossible,computethenumber ofreturnedrows.
*/ while ((tl= ti++))
{
TABLE_LIST *embedded; for (embedded= tl ; embedded; embedded= embedded->embedding)
{ if (embedded->on_expr) break;
} if (embedded) /* Don't replace expression on a table that is part of an outer join */
{
outer_tables|= tl->table->map;
/* Prepare to capture the MIN/MAX row for the optimizer context */
Opt_ctx_recorder_state state; if (thd->opt_ctx_recorder)
thd->opt_ctx_recorder->prepare_captured_row_read(table, &state);
if (!table->const_table)
{ if (likely(!(error= table->file->ha_index_init((uint) ref.key, 1))))
error= (is_max ?
get_index_max_value(table, &ref, range_fl, reverse) :
get_index_min_value(table, &ref, item_field, range_fl,
prefix_len, reverse));
} /* Verify that the read tuple indeed matches the search key */ if (!error &&
reckey_in_range(is_max, &ref, item_field->field,
conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND;
/* Capture the MIN/MAX row for the optimizer context */ if (Optimizer_context_recorder *rec= thd->opt_ctx_recorder)
{ if (!error)
rec->record_current_table_row(table);
rec->finish_captured_row_read(&state);
} if (!table->const_table)
{
table->file->ha_end_keyread();
table->file->ha_index_end();
}
table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL); if (error)
{ if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); // No rows matching WHERE /* HA_ERR_LOCK_DEADLOCK or some other error */
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
removed_tables|= table->map;
} elseif (!expr->const_item() || !is_exact_count || conds)
{ /* Theoptimizationisnotapplicableinbothcases: (a)'expr'isanon-constantexpression.Thenwecan't replace'expr'byaconstant. (b)'expr'isaconstant.AccordingtoANSI,MIN/MAXmustreturn NULLifthequerydoesnotreturnanyrows.Thus,ifwearenot abletodetermineifthequeryreturnsanyrows,wecan'tapply theoptimizationandreplaceMIN/MAXwithaconstant. (c)thereisaWHEREclause.TheWHEREconditionsmayresultin anemptyresult,buttheclausecannotbetakenintoaccounthere.
*/
const_result= 0; break;
}
item_sum->set_aggregator(thd,
item_sum->has_with_distinct() ?
Aggregator::DISTINCT_AGGREGATOR :
Aggregator::SIMPLE_AGGREGATOR); /* Ifcount==0(sois_exact_count==TRUE)and there'renoouterjoins,settoNULL, otherwisesettotheconstantvalue.
*/ if (!count && !outer_tables)
{
item_sum->aggregator_clear();
} else
{
item_sum->reset_and_add(); /* Saveareferencetotheitemforpossiblerollback ofthemin/maxoptimizationsforthisselect
*/
thd->lex->current_select->min_max_opt_list.push_back(item_sum);
}
item_sum->make_const();
recalc_const_item= 1; break;
} default:
const_result= 0; break;
}
} elseif (const_result)
{ if (recalc_const_item)
item->update_used_tables(); if (!item->const_item() && item->type() != Item::WINDOW_FUNC_ITEM)
const_result= 0;
}
}
if (unlikely(thd->is_error()))
DBUG_RETURN(thd->get_stmt_da()->sql_errno());
/* Ifwehaveawhereclause,wecanonlyignoresearchinginthe tablesifMIN/MAXoptimisationreplacedallusedtables Wedonotusereplacedvaluesincaseof: SELECTMIN(key)FROMtable_1,empty_table removed_tablesis!=0ifwehaveusedMIN()orMAX().
*/ if (removed_tables && used_tables != removed_tables)
const_result= 0; // We didn't remove all tables
DBUG_RETURN(const_result);
}
staticbool check_item1_shorter_item2(Item *item1, Item *item2)
{ if (item1->cmp_type() == STRING_RESULT &&
item2->cmp_type() == STRING_RESULT)
{ int len1= item1->max_length / item1->collation.collation->mbmaxlen; int len2= item2->max_length / item2->collation.collation->mbmaxlen; return len1 < len2;
} returnfalse; /* When the check is not applicable, it means "not bigger" */
}
staticbool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
KEY_PART_INFO *field_part, COND *cond,
key_part_map *key_part_used, uint *range_fl,
uint *prefix_len)
{
DBUG_ENTER("matching_cond"); if (!cond)
DBUG_RETURN(TRUE);
Field *field= field_part->field;
table_map cond_used_tables= cond->used_tables(); if (cond_used_tables & OUTER_REF_TABLE_BIT)
{
DBUG_RETURN(FALSE);
} if (!(cond_used_tables & field->table->map) &&
MY_TEST(cond_used_tables & ~PSEUDO_TABLE_BITS))
{ /* Condition doesn't restrict the used table */
DBUG_RETURN(!cond->const_item());
} elseif (cond->is_expensive())
DBUG_RETURN(FALSE); if (cond->type() == Item::COND_ITEM)
{ if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
DBUG_RETURN(FALSE);
/* AND */
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item; while ((item= li++))
{ if (!matching_cond(max_fl, ref, keyinfo, field_part, item,
key_part_used, range_fl, prefix_len))
DBUG_RETURN(FALSE);
}
DBUG_RETURN(TRUE);
}
if (cond->type() != Item::FUNC_ITEM)
DBUG_RETURN(FALSE); // Not operator, can't optimize
bool eq_type= 0; // =, <=> or IS NULL bool is_null_safe_eq= FALSE; // The operator is NULL safe, e.g. <=> bool noeq_type= 0; // < or > bool less_fl= 0; // < or <= bool is_null= 0; // IS NULL bool between= 0; // BETWEEN ... AND ...
switch (((Item_func*) cond)->functype()) { case Item_func::ISNULL_FUNC:
is_null= 1; /* fall through */ case Item_func::EQ_FUNC:
eq_type= TRUE; break; case Item_func::EQUAL_FUNC:
eq_type= is_null_safe_eq= TRUE; break; case Item_func::LT_FUNC:
noeq_type= 1; /* fall through */ case Item_func::LE_FUNC:
less_fl= 1; break; case Item_func::GT_FUNC:
noeq_type= 1; /* fall through */ case Item_func::GE_FUNC: break; case Item_func::BETWEEN: if (((Item_func_between*) cond)->negated)
DBUG_RETURN(FALSE);
between= 1; break; case Item_func::MULT_EQUAL_FUNC:
eq_type= 1; break; default:
DBUG_RETURN(FALSE); // Can't optimize function
}
Item *args[3]; bool inv;
/* Test if this is a comparison of a field and constant */ if (!simple_pred((Item_func*) cond, args, &inv))
DBUG_RETURN(FALSE);
/* Check if field is part of the tested partial key */
uchar *key_ptr= ref->key_buff;
KEY_PART_INFO *part; for (part= keyinfo->key_part; ; key_ptr+= part++->store_length)
{ if (part > field_part)
DBUG_RETURN(FALSE); // Field is beyond the tested parts if (part->field->eq(((Item_field*) args[0])->field)) break; // Found a part of the key for the field
}
bool is_field_part= part == field_part; if (!(is_field_part || eq_type))
DBUG_RETURN(FALSE);
key_part_map org_key_part_used= *key_part_used; if (eq_type || between || max_fl == less_fl)
{
uint length= (uint)(key_ptr-ref->key_buff)+part->store_length; if (ref->key_length < length)
{ /* Ultimately ref->key_length will contain the length of the search key */
ref->key_length= length;
ref->key_parts= (uint)(part - keyinfo->key_part) + 1;
} if (!*prefix_len && part+1 == field_part)
*prefix_len= length; if (is_field_part && eq_type)
*prefix_len= ref->key_length;
/* Check whether the index component is partial */
Field *part_field= table->field[part->fieldnr-1]; if ((part_field->flags & BLOB_FLAG) ||
part->length < part_field->key_length()) break;
staticint maxmin_in_range(bool max_fl, Field* field, COND *cond)
{ /* If AND/OR condition */ if (cond->type() == Item::COND_ITEM)
{
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item; while ((item= li++))
{ if (maxmin_in_range(max_fl, field, item)) return1;
} return0;
}
if (cond->used_tables() != field->table->map) return0; bool less_fl= 0; switch (((Item_func*) cond)->functype()) { case Item_func::BETWEEN: return cond->val_bool() == false; // Return 1 if WHERE is false case Item_func::LT_FUNC: case Item_func::LE_FUNC:
less_fl= 1; /* fall through */ case Item_func::GT_FUNC: case Item_func::GE_FUNC:
{
Item *item= ((Item_func*) cond)->arguments()[1]; /* In case of 'const op item' we have to swap the operator */ if (!item->const_item())
less_fl= 1-less_fl; /* Weonlyhavetochecktheexpressionifweareusinganexpressionlike SELECTMAX(b)FROMt1WHEREa=constANDb>const notfor SELECTMAX(b)FROMt1WHEREa=constANDb<const
*/ if (max_fl != less_fl) return cond->val_bool() == false; // Return 1 if WHERE is false return0;
} default: break; // Ignore
} return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.30 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.