Show
added a comment - Trying the original testcase from http://bugs.mysql.com/bug.php?id=36817:
Clean MariaDB 10.1:
MariaDB [j11]> CREATE TABLE `a` (
-> `id1` int(10) unsigned NOT NULL auto_increment,
-> `id2` tinyint(3) unsigned NOT NULL default '0',
-> `id3` tinyint(3) unsigned NOT NULL default '0',
-> `id4` int(10) unsigned NOT NULL default '0',
-> `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id1`),
-> KEY `id2` (`id2`,`id3`,`id4`,`date`),
-> KEY `id2_2` (`id2`,`id3`,`date`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.08 sec)
MariaDB [j11]> INSERT INTO a (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1);
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
MariaDB [j11]> EXPLAIN SELECT id1 FROM a WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
+------+-------------+-------+------+---------------+------+---------+-------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-----------------------------+
| 1 | SIMPLE | a | ref | id2,id2_2 | id2 | 2 | const,const | 3 | Using where; Using filesort |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-----------------------------+
MariaDB [j11]> DROP TABLE IF EXISTS a;
MariaDB [j11]> CREATE TABLE `a` (
-> `id1` int(10) unsigned NOT NULL auto_increment,
-> `id2` tinyint(3) unsigned NOT NULL default '0',
-> `id3` tinyint(3) unsigned NOT NULL default '0',
-> `id4` int(10) unsigned NOT NULL default '0',
-> `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id1`),
-> KEY `id2` (`id2`,`id3`,`date`),
-> KEY `id2_2` (`id2`,`id3`,`id4`,`date`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.06 sec)
MariaDB [j11]> INSERT INTO a (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
MariaDB [j11]> EXPLAIN SELECT id1 FROM a WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
| 1 | SIMPLE | a | ref | id2,id2_2 | id2 | 2 | const,const | 3 | Using where |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
10.1 tree with fixes for MDEV-6384 , MDEV-6480 :
MariaDB [j11]> CREATE TABLE `a` (
-> `id1` int(10) unsigned NOT NULL auto_increment,
-> `id2` tinyint(3) unsigned NOT NULL default '0',
-> `id3` tinyint(3) unsigned NOT NULL default '0',
-> `id4` int(10) unsigned NOT NULL default '0',
-> `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id1`),
-> KEY `id2` (`id2`,`id3`,`id4`,`date`),
-> KEY `id2_2` (`id2`,`id3`,`date`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.12 sec)
MariaDB [j11]> INSERT INTO a (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
MariaDB [j11]> EXPLAIN SELECT id1 FROM a WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| 1 | SIMPLE | a | range | id2,id2_2 | id2_2 | 2 | NULL | 3 | Using where |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
MariaDB [j11]> DROP TABLE IF EXISTS a;
Query OK, 0 rows affected (0.00 sec)
MariaDB [j11]> CREATE TABLE `a` (
-> `id1` int(10) unsigned NOT NULL auto_increment,
-> `id2` tinyint(3) unsigned NOT NULL default '0',
-> `id3` tinyint(3) unsigned NOT NULL default '0',
-> `id4` int(10) unsigned NOT NULL default '0',
-> `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id1`),
-> KEY `id2` (`id2`,`id3`,`date`),
-> KEY `id2_2` (`id2`,`id3`,`id4`,`date`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.07 sec)
MariaDB [j11]> INSERT INTO a (id2,id3,id4) VALUES (1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,0,1),(1,2,1),(1,3,1);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
MariaDB [j11]> EXPLAIN SELECT id1 FROM a WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4;
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
| 1 | SIMPLE | a | ref | id2,id2_2 | id2 | 2 | const,const | 3 | Using where |
+------+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
With MariaDB 5.5 and Yoshinori's example, I get the best index:
MariaDB [j3]> explain select * from a where k2=5 order by k3 limit 2;
-----
-----------------------------------------------------------------+-----
-----------------------------------------------------------------+-----
-----------------------------------------------------------------+This seems to be pure chance though: range optimizer choses the best index with no regards to ORDER BY LIMIT clause, it has identical costs for indexes i1 and i2, and the choice may vary because of how floating-point numbers are compared.
If it choses i2, we're lucky. If it choses i1, then ORDER BY optimization code will not be able to figure out that using i1 would have produced a cheaper plan. This is probably where part of the problem is.