Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-24621

In bulk insert, pre-sort and build indexes one page at a time

Details

    Description

      In MDEV-515, the original intention was to do 2 things to speed up INSERT to an empty table or partition:

      1. Stop writing undo log records for each inserted record, and instead write just one saying that the table was empty.
      2. When the table was empty, pre-sort the records for each index, and build the indexes one page at a time, instead of the current one unsorted record at a time.

      The undo logging change turned out to be rather challenging on its own, because it affects MVCC and locking as well. Preventing the useless undo logging should speed up ROLLBACK and recovery, and also the purge of history, compensating for MDEV-12288. Hence, it makes sense to complete MDEV-515 in the limited form.

      The purpose of this task is to make INSERT into an empty table or partition even more efficient by making use of sorting. We expect data loads into huge tables with many secondary indexes to become faster. The change buffer (MDEV-11634) should no longer come into play in this case. (Huge loads into nonempty tables will be unaffected by this enhancement.)

      After implementation comments:
      The following queries will use the new optimization:

      • CREATE ... SELECT
      • Inserting into an empty table together with SET STATEMENT unique_checks=0,foreign_key_checks=0 FOR ...
        • INSERT statement
        • INSERT ... SELECT
        • LOAD DATA INFILE

      Insert into an empty table without unique_checks=0,foreign_key_checks=0 will NOT be optimized.

      Attachments

        Issue Links

          Activity

            I must say that it is encouraging to see such time savings for a simple benchmark that did not even include secondary indexes. With secondary indexes, I would expect the performance difference to be even bigger, between row-by-row inserts into each index, and the merge sort and bulk insert of one index at a time.

            marko Marko Mäkelä added a comment - I must say that it is encouraging to see such time savings for a simple benchmark that did not even include secondary indexes. With secondary indexes, I would expect the performance difference to be even bigger, between row-by-row inserts into each index, and the merge sort and bulk insert of one index at a time.

            --source include/have_innodb.inc
            --source include/have_sequence.inc
            create table t1(f1 int not null primary key, b char(255) CHARACTER SET utf8)engine=innodb;
            INSERT INTO t1(f1) SELECT * FROM seq_1_to_1000000;
            --source include/restart_mysqld.inc - Here t1 size is 32 MB
            alter table t1 force, algorithm=inplace;
            --source include/restart_mysqld.inc - Here t1 size is 36 MB
            drop table t1;
            

            Inplace alter table code increases the file size of the table by 4MB. Bulk insert code uses the same code path as inplace alter code. This file size
            increases issue should affect 10.2+ onwards.

            thiru Thirunarayanan Balathandayuthapani added a comment - --source include/have_innodb.inc --source include/have_sequence.inc create table t1(f1 int not null primary key, b char(255) CHARACTER SET utf8)engine=innodb; INSERT INTO t1(f1) SELECT * FROM seq_1_to_1000000; --source include/restart_mysqld.inc - Here t1 size is 32 MB alter table t1 force, algorithm=inplace; --source include/restart_mysqld.inc - Here t1 size is 36 MB drop table t1; Inplace alter table code increases the file size of the table by 4MB. Bulk insert code uses the same code path as inplace alter code. This file size increases issue should affect 10.2+ onwards.

            thiru, I got some data from axel regarding a performance regression, but it did not have good stack traces. I reread the code changes, and I suspect that the performance regression is due to the SQL layer change that also serg asked about. Could we replace innodb_bulk_insert_write() and its caller with a small addition to ha_innobase::reset()?

            marko Marko Mäkelä added a comment - thiru , I got some data from axel regarding a performance regression, but it did not have good stack traces. I reread the code changes, and I suspect that the performance regression is due to the SQL layer change that also serg asked about. Could we replace innodb_bulk_insert_write() and its caller with a small addition to ha_innobase::reset() ?

            This is still causing some performance regression for normal DML workload in a case when bulk loading was not used at all.

            marko Marko Mäkelä added a comment - This is still causing some performance regression for normal DML workload in a case when bulk loading was not used at all.

            Performance seems to be acceptable now.

            marko Marko Mäkelä added a comment - Performance seems to be acceptable now.

            People

              thiru Thirunarayanan Balathandayuthapani
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              12 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.