[MDEV-13121] Optimize String processing in Protocol::send() Created: 2017-06-19  Updated: 2023-11-28

Status: Open
Project: MariaDB Server
Component/s: Data types, OTHER
Fix Version/s: 10.11

Type: Task Priority: Major
Reporter: Alexander Barkov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Under terms of MDEV-10306 we changed a few Item_func descendants to return the result in the String passed as a parameter to val_str() instead of the class member such as tmp_value. This fixed incorrect results, but caused more my_alloc / my_free.

Consider this script:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a VARCHAR(500));
INSERT INTO t1  VALUES (REPEAT('a',500)),(REPEAT('b',500));
SELECT HEX(a) FROM t1;

This is an except from Protocol::send_result_set_row:

bool Protocol::send_result_set_row(List<Item> *row_items)
{
  char buffer[MAX_FIELD_WIDTH];
  String str_buffer(buffer, sizeof (buffer), &my_charset_bin);
  List_iterator_fast<Item> it(*row_items);
  ...
  for (Item *item= it++; item; item= it++)
  {
    if (item->send(this, &str_buffer))
    ...
  }
}

Notice, the local buffer str_buffer is shared between columns of the same record, but it is not shared between multiple records of the same result set.

The buffer str_buffer is recursively passed to Item_func_hex::val_str_ascii(), which has to do alloc(1001) on every row, because the result does not fit into
MAX_FIELD_WIDTH bytes originally available in str_buffer.

Under terms of this task we will:

  • Add a new String member in Protocol, e.g. Protocol::tmp_value.
  • Fix Protocol::send_result_set_row() to use this new member instead of the local buffer

This will allow to share the memory allocated on the first row for the consequent rows.


Generated at Thu Feb 08 08:03:03 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.