Bug #109601 Apply partition pruning if all insert rows have non-null values on autoinc field
Submitted: 12 Jan 2023 9:00 Modified: 12 Jan 2023 9:37
Reporter: Hope Lee (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[12 Jan 2023 9:00] Hope Lee
Description:
Currently if an auto increment field is part of the partition expression, the optimizer won't do partition pruning when inserting values. But actually, if the values of auto increment field are explicitly assigned in all insert rows and they are neither NULL nor 0(not with NO_AUTO_VALUE_ON_ZERO sql_mode), we can do partition pruning to improve performance.

This is also a TODO thing left by the developer in function partition_info::can_prune_insert():

  if (table->found_next_number_field) {
    /*
      If the field is used in the partitioning expression, we cannot prune.
      TODO: If all rows have not null values and
      is not 0 (with NO_AUTO_VALUE_ON_ZERO sql_mode), then pruning is possible!
    */
    if (bitmap_is_set(&full_part_field_set,
                      table->found_next_number_field->field_index()))
      return false;

How to repeat:
CREATE TABLE `sbtest1` (
  `id` int NOT NULL AUTO_INCREMENT,
  `k` int NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB
PARTITION BY RANGE (`id`)
(PARTITION p0 VALUES LESS THAN (1001) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (2001) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (3001) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (4001) ENGINE = InnoDB,
 PARTITION p4 VALUES LESS THAN (5001) ENGINE = InnoDB);

mysql-8.0.30 > EXPLAIN INSERT INTO sbtest1 VALUES (5, 10, 'aaz', 'kox'), (100, 92, 'hope', 'carmen');
+----+-------------+---------+----------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table   | partitions     | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+---------+----------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | INSERT      | sbtest1 | p0,p1,p2,p3,p4 | ALL  | NULL          | NULL | NULL    | NULL | NULL |     NULL | NULL  |
+----+-------------+---------+----------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

We know the above two records will be inserted to partition p0, but the explained result shows this SQL will involve all partitions.

Suggested fix:
Apply partition pruning when all rows have non-null values on the auto increment field. See the following patch.
[12 Jan 2023 9:02] Hope Lee
Support partition pruning when autoinc field is assigned  non-null value in INSERT command

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: 0001-Support-partition-pruning-when-autoinc-field-is-assi.patch (application/octet-stream, text), 40.67 KiB.

[12 Jan 2023 9:37] MySQL Verification Team
Hello Hope Lee,

Thank you for the report and contribution.

regards,
Umesh