From 763af1a8a3a894df7326303b062bc55121103cb0 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya <psergey@askmonty.org> Date: Mon, 1 Apr 2013 18:03:14 +0400 Subject: [PATCH] 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. --- sql/opt_range.cc | 15 ++++++++------- sql/opt_range.h | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index df1d691ca58..2cab05b26ab 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -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 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) 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; diff --git a/sql/opt_range.h b/sql/opt_range.h index d4b92015042..17bb6d16da8 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -310,7 +310,7 @@ class QUICK_SELECT_I 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 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I 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 @@ class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I #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 -- 2.30.9