Commit 5fbd0192 authored by osku's avatar osku

Optimize BLOB selects by using prebuilt->blob_heap directly instead of first

reading BLOB data to a temporary heap and then copying it to
prebuilt->blob_heap.
parent 135e5219
...@@ -2573,6 +2573,7 @@ row_sel_store_mysql_rec( ...@@ -2573,6 +2573,7 @@ row_sel_store_mysql_rec(
{ {
mysql_row_templ_t* templ; mysql_row_templ_t* templ;
mem_heap_t* extern_field_heap = NULL; mem_heap_t* extern_field_heap = NULL;
mem_heap_t* heap;
byte* data; byte* data;
ulint len; ulint len;
ulint i; ulint i;
...@@ -2597,7 +2598,19 @@ row_sel_store_mysql_rec( ...@@ -2597,7 +2598,19 @@ row_sel_store_mysql_rec(
ut_a(!prebuilt->trx->has_search_latch); ut_a(!prebuilt->trx->has_search_latch);
extern_field_heap = mem_heap_create(UNIV_PAGE_SIZE); if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
if (prebuilt->blob_heap == NULL) {
prebuilt->blob_heap =
mem_heap_create(UNIV_PAGE_SIZE);
}
heap = prebuilt->blob_heap;
} else {
extern_field_heap =
mem_heap_create(UNIV_PAGE_SIZE);
heap = extern_field_heap;
}
/* NOTE: if we are retrieving a big BLOB, we may /* NOTE: if we are retrieving a big BLOB, we may
already run out of memory in the next call, which already run out of memory in the next call, which
...@@ -2605,7 +2618,7 @@ row_sel_store_mysql_rec( ...@@ -2605,7 +2618,7 @@ row_sel_store_mysql_rec(
data = btr_rec_copy_externally_stored_field(rec, data = btr_rec_copy_externally_stored_field(rec,
offsets, templ->rec_field_no, &len, offsets, templ->rec_field_no, &len,
extern_field_heap); heap);
ut_a(len != UNIV_SQL_NULL); ut_a(len != UNIV_SQL_NULL);
} else { } else {
...@@ -2616,48 +2629,6 @@ row_sel_store_mysql_rec( ...@@ -2616,48 +2629,6 @@ row_sel_store_mysql_rec(
} }
if (len != UNIV_SQL_NULL) { if (len != UNIV_SQL_NULL) {
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
ut_a(prebuilt->templ_contains_blob);
/* A heuristic test that we can allocate the
memory for a big BLOB. We have a safety margin
of 1000000 bytes. Since the test takes some
CPU time, we do not use it for small BLOBs. */
if (UNIV_UNLIKELY(len > 2000000)
&& UNIV_UNLIKELY(!ut_test_malloc(
len + 1000000))) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: could not allocate %lu + 1000000 bytes to retrieve\n"
"InnoDB: a big column. Table name ", (ulong) len);
ut_print_name(stderr,
prebuilt->trx,
prebuilt->table->name);
putc('\n', stderr);
if (extern_field_heap) {
mem_heap_free(
extern_field_heap);
}
return(FALSE);
}
/* Copy the BLOB data to the BLOB heap of
prebuilt */
if (prebuilt->blob_heap == NULL) {
prebuilt->blob_heap =
mem_heap_create(len);
}
data = memcpy(mem_heap_alloc(
prebuilt->blob_heap, len),
data, len);
}
row_sel_field_store_in_mysql_format( row_sel_field_store_in_mysql_format(
mysql_rec + templ->mysql_col_offset, mysql_rec + templ->mysql_col_offset,
templ, data, len); templ, data, len);
......
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