Skip to content
  • Praveenkumar Hulakund's avatar
    1e20f5bc
    Bug#30594613 - SIMPLE TABLE CHECK CONSTRAINT SHOW PERFORMANCE REGRESSION FOR... · 1e20f5bc
    Praveenkumar Hulakund authored
    Bug#30594613 - SIMPLE TABLE CHECK CONSTRAINT SHOW PERFORMANCE REGRESSION FOR READ OPS (POINT SELECTS)
    
    Issue here is, benchmark of check constraints showed performance
    regression for read (POINT SELECT) tests. The regressions observed
    is around 27% and profiling showed lot of additional Performance
    Schema (PFS) instrumentation calls related to memory allocation
    and free (i.e pfs_memory_alloc_v1 and pfs_memory_free_v1).
    
    If a check constraint is defined on the table then while opening
    a table, check constraint information is stored in a TABLE_SHARE
    and TABLE instance. While populating a TABLE_SHARE instance, memory
    is allocated for following elements in the "TABLE_SHARE::mem_root",
    
       1.a) Mem_root_array<Sql_check_constraint_share *> to hold the
            check constraint information.
    
       1.b) Sql_check_constraint_share instance for each check
            constraint.
    
       1.c) Check constraint name.
    
       1.d) Check constraint expression string.
    
    While populating TABLE instance from a TABLE_SHARE, memory is
    allocated for following elements in the "TABLE::mem_root".
    
      2.a) Mem_root_array<Sql_table_check_constraint *> to hold the
           check constraint information.
    
      2.b) Sql_table_check_constraint instance for each check constraint.
    
      2.c) Check constraint name.
    
      2.d) Check constraint expression string.
    
      2.e) Value_generator instance to hold the information about
           itemized expression.
    
      For following elements memory is allocated in the THD::mem_root
      while populating a TABLE instance,
    
      2.f) Value_generator instance and expression string used for
           expression unpack operation.
    
    All allocations here are in the MEM_ROOT instance and ideally should
    be faster as chunk of heap memory is pre-allocated. But issue here
    is, for every allocation bookkeeping is done by the PFS. As a result,
    profiling of point select performance tests shows following data,
    
      0.25%     +6.61%  mysqld            [.] pfs_memory_free_v1
      0.31%     +5.86%  mysqld            [.] pfs_memory_alloc_v1
     [^ is from the bug report]
    
    To fix this issue following changes are done,
    
    A. Reduce number of memory allocation calls:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The aim here is to reduce allocation calls which intern reduces
    PFS instrumentation calls.
    
      A.1) In 1.a array of pointers to Sql_check_constraint_share is
           allocated and for each check constraint memory is allocated
           in 1.b. PFS instrumentation hooks are called in 1.a and
           1.b.
    
           To reduce number of allocation calls, array of
           Sql_check_constraint_share array(i.e. Mem_root_array<
           Sql_check_constraint_share>) is allocated. This change
           reduces PFS calls for 1.b.
    
      A.2) Similarly in 2.a array of pointers is allocated for 2.b.
    
           To reduce number of allocation calls, array of
           Sql_table_check_constraint array(i.e. Mem_root_array<
           Sql_table_check_constraint>) is allocated. This change
           reduces PFS calls for 2.b.
    
      A.3) Patch removes, 2.c and 2.d. Name and expression string
           are referred from the 1.c and 1.d of a TABLE_SHARE.
    
      A.4) 2.f is replaced with the allocation of Value_generator
           instance in the stack area.
    
      A.5) dd::String_type is used to hold error string. String is
           used to report an error if check constraint expression
           itemizing fails. But allocation in dd::String_type also
           invokes PFS instrumentation hooks.
    
           Replaced this with std::string. PFS instrumentation hooks
           are not invoked for std::string.
    
    With this change, performance regression reduced from 27% to ~4%.
    Overhead of ~4% includes cost to unpack check constraint expression.
    Check constraint, generated columns (and default expression) uses
    the same expression unpack module and shows around 3-4% degradation.
    
    Patch also fixes test case in the check_constraints.test. Test
    case gets information from INFORMATION_SCHEMA.CHECK_CONSTRAINTS.
    Test case may fail sporadically due to order mismatch. Fixed
    test case by sorting the results using ORDER BY clause.
    
    Change-Id: Id1b16c46e28565f2941810ae70f97ab717870d22
    1e20f5bc
    Bug#30594613 - SIMPLE TABLE CHECK CONSTRAINT SHOW PERFORMANCE REGRESSION FOR...
    Praveenkumar Hulakund authored
    Bug#30594613 - SIMPLE TABLE CHECK CONSTRAINT SHOW PERFORMANCE REGRESSION FOR READ OPS (POINT SELECTS)
    
    Issue here is, benchmark of check constraints showed performance
    regression for read (POINT SELECT) tests. The regressions observed
    is around 27% and profiling showed lot of additional Performance
    Schema (PFS) instrumentation calls related to memory allocation
    and free (i.e pfs_memory_alloc_v1 and pfs_memory_free_v1).
    
    If a check constraint is defined on the table then while opening
    a table, check constraint information is stored in a TABLE_SHARE
    and TABLE instance. While populating a TABLE_SHARE instance, memory
    is allocated for following elements in the "TABLE_SHARE::mem_root",
    
       1.a) Mem_root_array<Sql_check_constraint_share *> to hold the
            check constraint information.
    
       1.b) Sql_check_constraint_share instance for each check
            constraint.
    
       1.c) Check constraint name.
    
       1.d) Check constraint expression string.
    
    While populating TABLE instance from a TABLE_SHARE, memory is
    allocated for following elements in the "TABLE::mem_root".
    
      2.a) Mem_root_array<Sql_table_check_constraint *> to hold the
           check constraint information.
    
      2.b) Sql_table_check_constraint instance for each check constraint.
    
      2.c) Check constraint name.
    
      2.d) Check constraint expression string.
    
      2.e) Value_generator instance to hold the information about
           itemized expression.
    
      For following elements memory is allocated in the THD::mem_root
      while populating a TABLE instance,
    
      2.f) Value_generator instance and expression string used for
           expression unpack operation.
    
    All allocations here are in the MEM_ROOT instance and ideally should
    be faster as chunk of heap memory is pre-allocated. But issue here
    is, for every allocation bookkeeping is done by the PFS. As a result,
    profiling of point select performance tests shows following data,
    
      0.25%     +6.61%  mysqld            [.] pfs_memory_free_v1
      0.31%     +5.86%  mysqld            [.] pfs_memory_alloc_v1
     [^ is from the bug report]
    
    To fix this issue following changes are done,
    
    A. Reduce number of memory allocation calls:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The aim here is to reduce allocation calls which intern reduces
    PFS instrumentation calls.
    
      A.1) In 1.a array of pointers to Sql_check_constraint_share is
           allocated and for each check constraint memory is allocated
           in 1.b. PFS instrumentation hooks are called in 1.a and
           1.b.
    
           To reduce number of allocation calls, array of
           Sql_check_constraint_share array(i.e. Mem_root_array<
           Sql_check_constraint_share>) is allocated. This change
           reduces PFS calls for 1.b.
    
      A.2) Similarly in 2.a array of pointers is allocated for 2.b.
    
           To reduce number of allocation calls, array of
           Sql_table_check_constraint array(i.e. Mem_root_array<
           Sql_table_check_constraint>) is allocated. This change
           reduces PFS calls for 2.b.
    
      A.3) Patch removes, 2.c and 2.d. Name and expression string
           are referred from the 1.c and 1.d of a TABLE_SHARE.
    
      A.4) 2.f is replaced with the allocation of Value_generator
           instance in the stack area.
    
      A.5) dd::String_type is used to hold error string. String is
           used to report an error if check constraint expression
           itemizing fails. But allocation in dd::String_type also
           invokes PFS instrumentation hooks.
    
           Replaced this with std::string. PFS instrumentation hooks
           are not invoked for std::string.
    
    With this change, performance regression reduced from 27% to ~4%.
    Overhead of ~4% includes cost to unpack check constraint expression.
    Check constraint, generated columns (and default expression) uses
    the same expression unpack module and shows around 3-4% degradation.
    
    Patch also fixes test case in the check_constraints.test. Test
    case gets information from INFORMATION_SCHEMA.CHECK_CONSTRAINTS.
    Test case may fail sporadically due to order mismatch. Fixed
    test case by sorting the results using ORDER BY clause.
    
    Change-Id: Id1b16c46e28565f2941810ae70f97ab717870d22
Loading