Commit 99c7017f authored by Sergey Petrunya's avatar Sergey Petrunya

MDEV-4240: mariadb 5.3.12 using more memory than MySQL 5.1 for an inefficient query

- Let index_merge allocate table handlers on quick select's MEM_ROOT,
  not on statement's MEM_ROOT. 
  This is crucial for big "range checked for each record" queries, where 
  index_merge can be created and deleted many times during query exection. 
  We should not make O(#rows) allocations on statement's MEM_ROOT.
parent 7b80eff3
...@@ -1970,7 +1970,7 @@ int QUICK_ROR_INTERSECT_SELECT::init() ...@@ -1970,7 +1970,7 @@ int QUICK_ROR_INTERSECT_SELECT::init()
1 error 1 error
*/ */
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc)
{ {
handler *save_file= file, *org_file; handler *save_file= file, *org_file;
my_bool org_key_read; my_bool org_key_read;
...@@ -1997,7 +1997,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -1997,7 +1997,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
} }
thd= head->in_use; thd= head->in_use;
if (!(file= head->file->clone(head->s->normalized_path.str, thd->mem_root))) if (!(file= head->file->clone(head->s->normalized_path.str, alloc)))
{ {
/* /*
Manually set the error flag. Note: there seems to be quite a few Manually set the error flag. Note: there seems to be quite a few
...@@ -2084,7 +2084,8 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -2084,7 +2084,8 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
0 OK 0 OK
other error code other error code
*/ */
int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler,
MEM_ROOT *alloc)
{ {
List_iterator_fast<QUICK_SELECT_WITH_RECORD> quick_it(quick_selects); List_iterator_fast<QUICK_SELECT_WITH_RECORD> quick_it(quick_selects);
QUICK_SELECT_WITH_RECORD *cur; QUICK_SELECT_WITH_RECORD *cur;
...@@ -2101,14 +2102,14 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -2101,14 +2102,14 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
There is no use of this->file. Use it for the first of merged range There is no use of this->file. Use it for the first of merged range
selects. selects.
*/ */
if (quick->init_ror_merged_scan(TRUE)) if (quick->init_ror_merged_scan(TRUE, alloc))
DBUG_RETURN(1); DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS); quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
} }
while ((cur= quick_it++)) while ((cur= quick_it++))
{ {
quick= cur->quick; quick= cur->quick;
if (quick->init_ror_merged_scan(FALSE)) if (quick->init_ror_merged_scan(FALSE, alloc))
DBUG_RETURN(1); DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS); quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
/* All merged scans share the same record buffer in intersection. */ /* All merged scans share the same record buffer in intersection. */
...@@ -2136,7 +2137,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) ...@@ -2136,7 +2137,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
int QUICK_ROR_INTERSECT_SELECT::reset() int QUICK_ROR_INTERSECT_SELECT::reset()
{ {
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset"); DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset");
if (!scans_inited && init_ror_merged_scan(TRUE)) if (!scans_inited && init_ror_merged_scan(TRUE, &alloc))
DBUG_RETURN(1); DBUG_RETURN(1);
scans_inited= TRUE; scans_inited= TRUE;
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects); List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
...@@ -2268,7 +2269,7 @@ int QUICK_ROR_UNION_SELECT::reset() ...@@ -2268,7 +2269,7 @@ int QUICK_ROR_UNION_SELECT::reset()
List_iterator_fast<QUICK_SELECT_I> it(quick_selects); List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++)) while ((quick= it++))
{ {
if (quick->init_ror_merged_scan(FALSE)) if (quick->init_ror_merged_scan(FALSE, &alloc))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
scans_inited= TRUE; scans_inited= TRUE;
......
...@@ -310,7 +310,7 @@ class QUICK_SELECT_I ...@@ -310,7 +310,7 @@ class QUICK_SELECT_I
0 Ok 0 Ok
other Error other Error
*/ */
virtual int init_ror_merged_scan(bool reuse_handler) virtual int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc)
{ DBUG_ASSERT(0); return 1; } { DBUG_ASSERT(0); return 1; }
/* /*
...@@ -448,7 +448,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I ...@@ -448,7 +448,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
uchar *cur_prefix); uchar *cur_prefix);
bool reverse_sorted() { return 0; } bool reverse_sorted() { return 0; }
bool unique_key_range(); bool unique_key_range();
int init_ror_merged_scan(bool reuse_handler); int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc);
void save_last_pos() void save_last_pos()
{ file->position(record); } { file->position(record); }
int get_type() { return QS_TYPE_RANGE; } int get_type() { return QS_TYPE_RANGE; }
...@@ -681,7 +681,7 @@ class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I ...@@ -681,7 +681,7 @@ class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose); void dbug_dump(int indent, bool verbose);
#endif #endif
int init_ror_merged_scan(bool reuse_handler); int init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc);
bool push_quick_back(MEM_ROOT *alloc, QUICK_RANGE_SELECT *quick_sel_range); bool push_quick_back(MEM_ROOT *alloc, QUICK_RANGE_SELECT *quick_sel_range);
class QUICK_SELECT_WITH_RECORD : public Sql_alloc class QUICK_SELECT_WITH_RECORD : public Sql_alloc
......
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