summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-11-07 16:52:56 +0100
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-04-18 00:29:51 +0300
commit1b1b89c2290db43c2055677abca51647bdcab1a1 (patch)
tree3837cf645ba88b951b30f38aae2cdc158f2d3329
parent695ebc902d0c763cf2ffd3916cb4ffc59b7a0506 (diff)
downloadmariadb-git-1b1b89c2290db43c2055677abca51647bdcab1a1.tar.gz
cleanup: cache the result of Rows_log_event::find_key()
-rw-r--r--sql/log_event_server.cc96
-rw-r--r--sql/rpl_utility.h26
2 files changed, 62 insertions, 60 deletions
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index 3bdc487bbcd..7085f7aa0db 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -7025,67 +7025,71 @@ record_compare_exit:
*/
int Rows_log_event::find_key()
{
- uint i, best_key_nr, last_part;
- KEY *key, *UNINIT_VAR(best_key);
+ DBUG_ASSERT(m_table);
+ 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;
DBUG_ENTER("Rows_log_event::find_key");
- DBUG_ASSERT(m_table);
-
- best_key_nr= MAX_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++)
+ if ((best_key_nr= tl->cached_key_nr) != ~0U)
+ DBUG_ASSERT(best_key_nr <= MAX_KEY); // use the cached value
+ else
{
- if (!m_table->s->keys_in_use.is_set(i))
- continue;
+ best_key_nr= MAX_KEY;
+
/*
- 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).
+ 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.
*/
- if ((key->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
+ for (i= 0, key= m_table->key_info; i < m_table->s->keys; i++, key++)
{
- 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;
+ if (!m_table->s->keys_in_use.is_set(i))
+ 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;
+ 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_key= key;
- best_rec_per_key= tmp;
+ 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;
}
+ m_key_nr= best_key_nr;
if (best_key_nr == MAX_KEY)
- {
m_key_info= NULL;
- DBUG_RETURN(0);
+ 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);
}
- // 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;
-
- DBUG_RETURN(0);;
+ DBUG_RETURN(0);
}
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 940345e3f00..f1d407268a1 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -249,37 +249,35 @@ private:
Extend the normal table list with a few new fields needed by the
slave thread, but nowhere else.
*/
-struct RPL_TABLE_LIST
- : public TABLE_LIST
+struct RPL_TABLE_LIST : public TABLE_LIST
{
- bool m_tabledef_valid;
- bool master_had_triggers;
table_def m_tabledef;
TABLE *m_conv_table;
const Copy_field *m_online_alter_copy_fields;
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,
thr_lock_type thr_lock_type,
table_def &&tabledef, bool master_had_trigers)
: 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_online_alter_copy_fields(NULL),
- m_online_alter_copy_fields_end(NULL)
+ m_online_alter_copy_fields(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,
table_def &&tabledef,
const Copy_field online_alter_copy_fields[],
const Copy_field *online_alter_copy_fields_end)
- : TABLE_LIST(table, lock_type),
- m_tabledef_valid(true),
- master_had_triggers(false),
- m_tabledef(std::move(tabledef)),
- m_conv_table(conv_table),
- m_online_alter_copy_fields(online_alter_copy_fields),
- m_online_alter_copy_fields_end(online_alter_copy_fields_end)
+ : TABLE_LIST(table, lock_type),
+ m_tabledef(std::move(tabledef)), m_conv_table(conv_table),
+ m_online_alter_copy_fields(online_alter_copy_fields),
+ m_online_alter_copy_fields_end(online_alter_copy_fields_end),
+ cached_key_nr(~0U), m_tabledef_valid(true), master_had_triggers(false)
{}
};