cleanup: cache the result of Rows_log_event::find_key()
This commit is contained in:
parent
6ecc90ae36
commit
d1e09972f0
@ -7105,67 +7105,71 @@ record_compare_exit:
|
|||||||
*/
|
*/
|
||||||
int Rows_log_event::find_key()
|
int Rows_log_event::find_key()
|
||||||
{
|
{
|
||||||
uint i, best_key_nr, last_part;
|
DBUG_ASSERT(m_table);
|
||||||
KEY *key, *UNINIT_VAR(best_key);
|
RPL_TABLE_LIST *tl= (RPL_TABLE_LIST*)m_table->pos_in_table_list;
|
||||||
|
uint i, best_key_nr;
|
||||||
|
KEY *key;
|
||||||
ulong UNINIT_VAR(best_rec_per_key), tmp;
|
ulong UNINIT_VAR(best_rec_per_key), tmp;
|
||||||
DBUG_ENTER("Rows_log_event::find_key");
|
DBUG_ENTER("Rows_log_event::find_key");
|
||||||
DBUG_ASSERT(m_table);
|
|
||||||
|
|
||||||
best_key_nr= MAX_KEY;
|
if ((best_key_nr= tl->cached_key_nr) != ~0U)
|
||||||
|
DBUG_ASSERT(best_key_nr <= MAX_KEY); // use the cached value
|
||||||
/*
|
else
|
||||||
Keys are sorted so that any primary key is first, followed by unique keys,
|
|
||||||
followed by any other. So we will automatically pick the primary key if
|
|
||||||
it exists.
|
|
||||||
*/
|
|
||||||
for (i= 0, key= m_table->key_info; i < m_table->s->keys; i++, key++)
|
|
||||||
{
|
{
|
||||||
if (!m_table->s->keys_in_use.is_set(i))
|
best_key_nr= MAX_KEY;
|
||||||
continue;
|
|
||||||
/*
|
|
||||||
We cannot use a unique key with NULL-able columns to uniquely identify
|
|
||||||
a row (but we can still select it for range scan below if nothing better
|
|
||||||
is available).
|
|
||||||
*/
|
|
||||||
if ((key->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
|
|
||||||
{
|
|
||||||
best_key_nr= i;
|
|
||||||
best_key= key;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
We can only use a non-unique key if it allows range scans (ie. skip
|
|
||||||
FULLTEXT indexes and such).
|
|
||||||
*/
|
|
||||||
last_part= key->user_defined_key_parts - 1;
|
|
||||||
DBUG_PRINT("info", ("Index %s rec_per_key[%u]= %lu",
|
|
||||||
key->name.str, last_part, key->rec_per_key[last_part]));
|
|
||||||
if (!(m_table->file->index_flags(i, last_part, 1) & HA_READ_NEXT))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
tmp= key->rec_per_key[last_part];
|
/*
|
||||||
if (best_key_nr == MAX_KEY || (tmp > 0 && tmp < best_rec_per_key))
|
Keys are sorted so that any primary key is first, followed by unique keys,
|
||||||
|
followed by any other. So we will automatically pick the primary key if
|
||||||
|
it exists.
|
||||||
|
*/
|
||||||
|
for (i= 0, key= m_table->key_info; i < m_table->s->keys; i++, key++)
|
||||||
{
|
{
|
||||||
best_key_nr= i;
|
if (!m_table->s->keys_in_use.is_set(i))
|
||||||
best_key= key;
|
continue;
|
||||||
best_rec_per_key= tmp;
|
/*
|
||||||
|
We cannot use a unique key with NULL-able columns to uniquely identify
|
||||||
|
a row (but we can still select it for range scan below if nothing better
|
||||||
|
is available).
|
||||||
|
*/
|
||||||
|
if ((key->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
|
||||||
|
{
|
||||||
|
best_key_nr= i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
We can only use a non-unique key if it allows range scans (ie. skip
|
||||||
|
FULLTEXT indexes and such).
|
||||||
|
*/
|
||||||
|
uint last_part= key->user_defined_key_parts - 1;
|
||||||
|
DBUG_PRINT("info", ("Index %s rec_per_key[%u]= %lu",
|
||||||
|
key->name.str, last_part, key->rec_per_key[last_part]));
|
||||||
|
if (!(m_table->file->index_flags(i, last_part, 1) & HA_READ_NEXT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tmp= key->rec_per_key[last_part];
|
||||||
|
if (best_key_nr == MAX_KEY || (tmp > 0 && tmp < best_rec_per_key))
|
||||||
|
{
|
||||||
|
best_key_nr= i;
|
||||||
|
best_rec_per_key= tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
tl->cached_key_nr= best_key_nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_key_nr == MAX_KEY)
|
|
||||||
{
|
|
||||||
m_key_info= NULL;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate buffer for key searches
|
|
||||||
m_key= (uchar *) my_malloc(PSI_INSTRUMENT_ME, best_key->key_length, MYF(MY_WME));
|
|
||||||
if (m_key == NULL)
|
|
||||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
|
||||||
m_key_info= best_key;
|
|
||||||
m_key_nr= best_key_nr;
|
m_key_nr= best_key_nr;
|
||||||
|
if (best_key_nr == MAX_KEY)
|
||||||
|
m_key_info= NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_key_info= m_table->key_info + best_key_nr;
|
||||||
|
// Allocate buffer for key searches
|
||||||
|
m_key= (uchar *) my_malloc(PSI_INSTRUMENT_ME, m_key_info->key_length, MYF(MY_WME));
|
||||||
|
if (m_key == NULL)
|
||||||
|
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,37 +249,35 @@ private:
|
|||||||
Extend the normal table list with a few new fields needed by the
|
Extend the normal table list with a few new fields needed by the
|
||||||
slave thread, but nowhere else.
|
slave thread, but nowhere else.
|
||||||
*/
|
*/
|
||||||
struct RPL_TABLE_LIST
|
struct RPL_TABLE_LIST : public TABLE_LIST
|
||||||
: public TABLE_LIST
|
|
||||||
{
|
{
|
||||||
bool m_tabledef_valid;
|
|
||||||
bool master_had_triggers;
|
|
||||||
table_def m_tabledef;
|
table_def m_tabledef;
|
||||||
TABLE *m_conv_table;
|
TABLE *m_conv_table;
|
||||||
const Copy_field *m_online_alter_copy_fields;
|
const Copy_field *m_online_alter_copy_fields;
|
||||||
const Copy_field *m_online_alter_copy_fields_end;
|
const Copy_field *m_online_alter_copy_fields_end;
|
||||||
|
uint cached_key_nr; // [0..MAX_KEY] if set, ~0U if unset
|
||||||
|
bool m_tabledef_valid;
|
||||||
|
bool master_had_triggers;
|
||||||
|
|
||||||
RPL_TABLE_LIST(const LEX_CSTRING *db_arg, const LEX_CSTRING *table_name_arg,
|
RPL_TABLE_LIST(const LEX_CSTRING *db_arg, const LEX_CSTRING *table_name_arg,
|
||||||
thr_lock_type thr_lock_type,
|
thr_lock_type thr_lock_type,
|
||||||
table_def &&tabledef, bool master_had_trigers)
|
table_def &&tabledef, bool master_had_trigers)
|
||||||
: TABLE_LIST(db_arg, table_name_arg, NULL, thr_lock_type),
|
: TABLE_LIST(db_arg, table_name_arg, NULL, thr_lock_type),
|
||||||
m_tabledef_valid(true), master_had_triggers(master_had_trigers),
|
|
||||||
m_tabledef(std::move(tabledef)), m_conv_table(NULL),
|
m_tabledef(std::move(tabledef)), m_conv_table(NULL),
|
||||||
m_online_alter_copy_fields(NULL),
|
m_online_alter_copy_fields(NULL), m_online_alter_copy_fields_end(NULL),
|
||||||
m_online_alter_copy_fields_end(NULL)
|
cached_key_nr(~0U), m_tabledef_valid(true),
|
||||||
|
master_had_triggers(master_had_trigers)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RPL_TABLE_LIST(TABLE *table, thr_lock_type lock_type, TABLE *conv_table,
|
RPL_TABLE_LIST(TABLE *table, thr_lock_type lock_type, TABLE *conv_table,
|
||||||
table_def &&tabledef,
|
table_def &&tabledef,
|
||||||
const Copy_field online_alter_copy_fields[],
|
const Copy_field online_alter_copy_fields[],
|
||||||
const Copy_field *online_alter_copy_fields_end)
|
const Copy_field *online_alter_copy_fields_end)
|
||||||
: TABLE_LIST(table, lock_type),
|
: TABLE_LIST(table, lock_type),
|
||||||
m_tabledef_valid(true),
|
m_tabledef(std::move(tabledef)), m_conv_table(conv_table),
|
||||||
master_had_triggers(false),
|
m_online_alter_copy_fields(online_alter_copy_fields),
|
||||||
m_tabledef(std::move(tabledef)),
|
m_online_alter_copy_fields_end(online_alter_copy_fields_end),
|
||||||
m_conv_table(conv_table),
|
cached_key_nr(~0U), m_tabledef_valid(true), master_had_triggers(false)
|
||||||
m_online_alter_copy_fields(online_alter_copy_fields),
|
|
||||||
m_online_alter_copy_fields_end(online_alter_copy_fields_end)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user