1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Optimize performance of my_bitmap

MDEV-33502 Slowdown when running nested statement with many partitions

This change was triggered to help some MariaDB users with close to
10000 bits in their bitmaps.

- Change underlaying storage to be 64 bit instead of 32bit.
  - This reduses number of loops to scan bitmaps.
  - This can cause some bitmaps to be 4 byte large.
- Ensure that all not used top-bits are always 0 (simplifes code as
  the last 64 bit storage is not a special case anymore).
- Use my_find_first_bit() to find the first set bit which is much faster
  than scanning trough things byte by byte and then bit by bit.

Other things:
- Added a bool to remember if my_bitmap_init() did allocate the bitmap
  array. my_bitmap_free() will only free arrays it did allocate.
  This allowed me to remove setting 'bitmap=0' before calling
  my_bitmap_free() for cases where the bitmap's where allocated externally.
- my_bitmap_init() sets bitmap to 0 in case of failure.
- Added 'universal' asserts to most bitmap functions.
- Change all remaining calls to bitmap_init() to my_bitmap_init().
  - To finish the change from 2014.
- Changed all usage of uint32 in my_bitmap.h to my_bitmap_map.
- Updated bitmap_copy() to handle bitmaps of different size.
- Removed const from bitmap_exists_intersection() as this caused casts
  on all usage.
- Removed not used function bitmap_set_above().
- Renamed create_last_word_mask() to create_last_bit_mask() (to match
  name changes in my_bitmap.cc)
- Extended bitmap-t with test for more bitmap functions.
This commit is contained in:
Monty
2024-02-18 17:30:01 +02:00
parent d4e1731fbc
commit b5d65fc105
18 changed files with 452 additions and 397 deletions

View File

@@ -1085,7 +1085,7 @@ void check_range_capable_PF(TABLE *table)
static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info)
{
uint32 *bitmap_buf;
my_bitmap_map *bitmap_buf;
uint bitmap_bits= part_info->num_subparts?
(part_info->num_subparts* part_info->num_parts):
part_info->num_parts;
@@ -1096,14 +1096,15 @@ static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info)
/* Allocate for both read and lock_partitions */
if (unlikely(!(bitmap_buf=
(uint32*) alloc_root(&part_info->table->mem_root,
bitmap_bytes * 2))))
(my_bitmap_map*) alloc_root(&part_info->table->mem_root,
bitmap_bytes * 2))))
DBUG_RETURN(TRUE);
my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE);
/* Use the second half of the allocated buffer for lock_partitions */
my_bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4),
bitmap_bits, FALSE);
my_bitmap_init(&part_info->lock_partitions,
(my_bitmap_map*) (((char*) bitmap_buf) + bitmap_bytes),
bitmap_bits, FALSE);
part_info->bitmaps_are_initialized= TRUE;
part_info->set_partition_bitmaps(NULL);
DBUG_RETURN(FALSE);