1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-35469 Heap tables are calling mallocs to often

Heap tables are allocated blocks to store rows according to
my_default_record_cache (mapped to the server global variable
 read_buffer_size).
This causes performance issues when the record length is big
(> 1000 bytes) and the my_default_record_cache is small.

Changed to instead split the default heap allocation to 1/16 of the
allowed space and not use my_default_record_cache anymore when creating
the heap. The allocation is also aligned to be just under a power of 2.

For some test that I have been running, which was using record length=633,
the speed of the query doubled thanks to this change.

Other things:
- Fixed calculation of max_records passed to hp_create() to take
  into account padding between records.
- Updated calculation of memory needed by heap tables. Before we
  did not take into account internal structures needed to access rows.
- Changed block sized for memory_table from 1 to 16384 to get less
  fragmentation. This also avoids a problem where we need 1K
  to manage index and row storage which was not counted for before.
- Moved heap memory usage to a separate test for 32 bit.
- Allocate all data blocks in heap in powers of 2. Change reported
  memory usage for heap to reflect this.

Reviewed-by: Sergei Golubchik <serg@mariadb.org>
This commit is contained in:
Monty
2024-11-21 12:28:57 +02:00
parent f20ee931d8
commit 52c29f3bdc
42 changed files with 316 additions and 198 deletions

View File

@@ -1,23 +1,20 @@
--source include/have_debug.inc
--source include/not_embedded.inc
--source include/have_sequence.inc
#
# Bug #28499: crash for grouping query when tmp_table_size is too small
#
CREATE TABLE t1 (
a varchar(32) character set utf8 collate utf8_bin NOT NULL,
b varchar(32) character set utf8 collate utf8_bin NOT NULL )
a varchar(128) character set utf8 collate utf8_bin NOT NULL,
b varchar(128) character set utf8 collate utf8_bin NOT NULL )
ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES
('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '),
('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'),
('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'),
('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'),
('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'),
('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK');
INSERT INTO t1
select concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29))),
concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29)))
from seq_1_to_128;
set tmp_table_size=1024;
set tmp_table_size=16384;
# Set debug flag so an error is returned when
# tmp table in query is converted from heap to myisam