Commit 7b07e332 authored by unknown's avatar unknown

InnoDB: Reduce memcpy() load in row_sel_pop_cached_row_for_mysql()

by copying only a prefix of the row that covers the requested
columns.


innobase/include/row0mysql.h:
  row_prebuilt_struct: Add field mysql_prefix_len
  in order to reduce memcpy() time in
  row_sel_pop_cached_row_for_mysql().
innobase/row/row0sel.c:
  row_sel_pop_cached_row_for_mysql(): memcpy() only
  mysql_prefix_len bytes instead of mysql_row_len.
sql/ha_innodb.cc:
  build_template(): Initialize prebuilt->mysql_prefix_len.
parent 4e0e9a3b
...@@ -599,6 +599,8 @@ struct row_prebuilt_struct { ...@@ -599,6 +599,8 @@ struct row_prebuilt_struct {
that was decided in ha_innodb.cc, that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(), ::store_lock(), ::external_lock(),
etc. */ etc. */
ulint mysql_prefix_len;/* byte offset of the end of
the last requested column */
ulint mysql_row_len; /* length in bytes of a row in the ulint mysql_row_len; /* length in bytes of a row in the
MySQL format */ MySQL format */
ulint n_rows_fetched; /* number of rows fetched after ulint n_rows_fetched; /* number of rows fetched after
......
...@@ -2849,8 +2849,9 @@ row_sel_pop_cached_row_for_mysql( ...@@ -2849,8 +2849,9 @@ row_sel_pop_cached_row_for_mysql(
mysql_row_templ_t* templ; mysql_row_templ_t* templ;
byte* cached_rec; byte* cached_rec;
ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->n_fetch_cached > 0);
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
if (prebuilt->keep_other_fields_on_keyread) if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread))
{ {
/* Copy cache record field by field, don't touch fields that /* Copy cache record field by field, don't touch fields that
are not covered by current key */ are not covered by current key */
...@@ -2877,7 +2878,7 @@ row_sel_pop_cached_row_for_mysql( ...@@ -2877,7 +2878,7 @@ row_sel_pop_cached_row_for_mysql(
else else
{ {
ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first], ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
prebuilt->mysql_row_len); prebuilt->mysql_prefix_len);
} }
prebuilt->n_fetch_cached--; prebuilt->n_fetch_cached--;
prebuilt->fetch_cache_first++; prebuilt->fetch_cache_first++;
......
...@@ -2618,6 +2618,8 @@ build_template( ...@@ -2618,6 +2618,8 @@ build_template(
ibool fetch_all_in_key = FALSE; ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE; ibool fetch_primary_key_cols = FALSE;
ulint i; ulint i;
/* byte offset of the end of last requested column */
ulint mysql_prefix_len = 0;
if (prebuilt->select_lock_type == LOCK_X) { if (prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we /* We always retrieve the whole clustered index record if we
...@@ -2738,6 +2740,11 @@ build_template( ...@@ -2738,6 +2740,11 @@ build_template(
get_field_offset(table, field); get_field_offset(table, field);
templ->mysql_col_len = (ulint) field->pack_length(); templ->mysql_col_len = (ulint) field->pack_length();
if (mysql_prefix_len < templ->mysql_col_offset
+ templ->mysql_col_len) {
mysql_prefix_len = templ->mysql_col_offset
+ templ->mysql_col_len;
}
templ->type = index->table->cols[i].type.mtype; templ->type = index->table->cols[i].type.mtype;
templ->mysql_type = (ulint)field->type(); templ->mysql_type = (ulint)field->type();
...@@ -2760,6 +2767,7 @@ skip_field: ...@@ -2760,6 +2767,7 @@ skip_field:
} }
prebuilt->n_template = n_requested_fields; prebuilt->n_template = n_requested_fields;
prebuilt->mysql_prefix_len = mysql_prefix_len;
if (index != clust_index && prebuilt->need_to_access_clustered) { if (index != clust_index && prebuilt->need_to_access_clustered) {
/* Change rec_field_no's to correspond to the clustered index /* Change rec_field_no's to correspond to the clustered index
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment