Bug #64097 mysqldump doesn't generate sorted data by PK for some InnoDB tables
Submitted: 22 Jan 2012 8:42 Modified: 22 Jan 2012 9:04
Reporter: Sadao Hiratsuka (Basic Quality Contributor) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: mysqldump Command-line Client Severity:S3 (Non-critical)
Version:5.1.61, 5.5.20 OS:Any
Assigned to: CPU Architecture:Any
Tags: mysqldump, qc

[22 Jan 2012 8:42] Sadao Hiratsuka
Description:
mysqldump doesn't generate sorted data by PK for some InnoDB tables.
So restoring the data will become very slow.

How to repeat:
CREATE TABLE `t` (
  `id1` int(11) NOT NULL DEFAULT '0',
  `id2` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id1`,`id2`),
  KEY `id2` (`id2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

DROP PROCEDURE generate;
DELIMITER //
CREATE PROCEDURE generate()
BEGIN
  DECLARE id1 INT;
  DECLARE id2 INT;
  SET id1 = 1;
  WHILE id1 <= 10 DO
    SET id2 = 1;
    WHILE id2 <= 10 DO
      INSERT INTO t (id1, id2) VALUES (id1, id2);
      SET id2 = id2 + 1;
    END WHILE;
    SET id1 = id1 + 1;
  END WHILE;
END
//
DELIMITER ;

$ mysqldump -u xxx -p xxx t > t.sql

<t.sql>
...
INSERT INTO `t` VALUES (1,1),(2,1),(3,1),(4,1),(5,1),
(6,1),(7,1),(8,1),(9,1),(10,1),(1,2),(2,2),
...

Suggested fix:
In this case, SQL Optimizer chooses the following plan.
But, in mysqldump, SQL Optimizer should choose a plan that uses PK.

+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | index | NULL          | id2  | 4       | NULL |  100 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+

Idea 1:
mysqldump automatically adds --order-by-primary option or 'FORCE INDEX (PRMARY)' clause for InnoDB tables.

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | index | NULL          | PRIMARY | 8       | NULL |  100 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

Idea 2:
SQL Optimizer choose a plan that uses PK for such InnoDB tables.

Thanks,
[22 Jan 2012 9:04] Valeriy Kravchuk
You are right. This problem is provoked by server:

mysql> explain select * from t\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: index
possible_keys: NULL
          key: id2
      key_len: 4
          ref: NULL
         rows: 100
        Extra: Using index
1 row in set (0.02 sec)

but mysqdump can avoid it by adding hint you suggested.