mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -1970,7 +1970,7 @@ int QUICK_ROR_INTERSECT_SELECT::init()
|
||||
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;
|
||||
my_bool org_key_read;
|
||||
@ -1997,7 +1997,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
|
||||
}
|
||||
|
||||
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
|
||||
@ -2084,7 +2084,8 @@ failure:
|
||||
0 OK
|
||||
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);
|
||||
QUICK_SELECT_WITH_RECORD *cur;
|
||||
@ -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
|
||||
selects.
|
||||
*/
|
||||
if (quick->init_ror_merged_scan(TRUE))
|
||||
if (quick->init_ror_merged_scan(TRUE, alloc))
|
||||
DBUG_RETURN(1);
|
||||
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
|
||||
}
|
||||
while ((cur= quick_it++))
|
||||
{
|
||||
quick= cur->quick;
|
||||
if (quick->init_ror_merged_scan(FALSE))
|
||||
if (quick->init_ror_merged_scan(FALSE, alloc))
|
||||
DBUG_RETURN(1);
|
||||
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
|
||||
/* 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)
|
||||
int 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);
|
||||
scans_inited= TRUE;
|
||||
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
|
||||
@ -2268,7 +2269,7 @@ int QUICK_ROR_UNION_SELECT::reset()
|
||||
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
|
||||
while ((quick= it++))
|
||||
{
|
||||
if (quick->init_ror_merged_scan(FALSE))
|
||||
if (quick->init_ror_merged_scan(FALSE, &alloc))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
scans_inited= TRUE;
|
||||
|
@ -310,7 +310,7 @@ public:
|
||||
0 Ok
|
||||
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; }
|
||||
|
||||
/*
|
||||
@ -448,7 +448,7 @@ public:
|
||||
uchar *cur_prefix);
|
||||
bool reverse_sorted() { return 0; }
|
||||
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()
|
||||
{ file->position(record); }
|
||||
int get_type() { return QS_TYPE_RANGE; }
|
||||
@ -681,7 +681,7 @@ public:
|
||||
#ifndef DBUG_OFF
|
||||
void dbug_dump(int indent, bool verbose);
|
||||
#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);
|
||||
|
||||
class QUICK_SELECT_WITH_RECORD : public Sql_alloc
|
||||
|
Reference in New Issue
Block a user