Bug #56453 wrong index selection
Submitted: 1 Sep 2010 14:21 Modified: 25 Oct 2016 16:03
Reporter: Valenti Jove Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S3 (Non-critical)
Version:mysql-5.1-telco-7.0 OS:Any
Assigned to: MySQL Verification Team CPU Architecture:Any
Tags: 7.0.16

[1 Sep 2010 14:21] Valenti Jove
Description:
The engine chooses the wrong index in a simple select query.

How to repeat:

My case:

mysql> select ID from t_e where e=2781 and p=23927 and ff is null;
+-----------+
| ID        |
+-----------+
| 130419083 |
+-----------+
1 row in set (10.36 sec)

mysql> explain select ID from t_e where e=2781 and p=23927 and ff is null;
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------+------+-----------------------------------+
| id | select_type | table  | type | possible_keys                                                                              | key             | key_len | ref   | rows | Extra                             |
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------+------+-----------------------------------+
|  1 | SIMPLE      | t_e | ref  | E_V,E_P,E_EF,E_PERS,E_VH,E_V_F                                   | E_V                     | 4       | const |   10 | Using where with pushed condition |
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------+------+-----------------------------------+
1 row in set (0.00 sec)

E_V is an index containing the (e,p,fi) columns, where fi is a datetime column that doesn't appear in the query.

In InnoDB, the query is fast and the explain is as following:

mysql> explain select ID from t_e where e=2781 and p=23927 and ff is null;
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------------------+------+--------------------------+
| id | select_type | table  | type | possible_keys                                                                              | key             | key_len | ref               | rows | Extra                    |
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------------------+------+--------------------------+
|  1 | SIMPLE      | t_e | ref  | E_V,E_P,E_EF,E_PERS,E_VH,E_V_F                                   | E_PERS | 18      | const,const,const |    5 | Using where; Using index |
+----+-------------+--------+------+--------------------------------------------------------------------------------------------+-----------------+---------+-------------------+------+--------------------------+
1 row in set (0.00 sec

E_PERS is an index containing the (e,p,ff) columns, and this should be the obvious index choice for this query because it contains the 3 columns of the query.

Back to the cluster, if we force the index, everything is ok:

mysql> select ID from t_e force index(e_pers) where e=2781 and p=23927 and ff is null;
+-----------+
| ID        |
+-----------+
| 130419083 |
+-----------+
1 row in set (0.01 sec)

e and p are ints, ff and fi are datetimes.

If we change the condition "ff is null" to ff="2010-04-29 20:31:10", same thing.

--------------------------------
Easy way to repeat it:

mysql> create table t (id int primary key, e int, p int, fi datetime, ff datetime) type=ndbcluster;
Query OK, 0 rows affected, 1 warning (0.45 sec)

mysql> create index t_idx1 on t (e,p,fi);
^[[AQuery OK, 0 rows affected (0.50 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> create index t_idx2 on t (e,p,ff);
Query OK, 0 rows affected (0.51 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into t (id,e,p,fi,ff) values(1,2,3,'2010-04-29 20:31:10','2010-04-29 20:31:10');
Query OK, 1 row affected (0.01 sec)

mysql> explain select id from t where e=2781 and p=23927 and ff is null;
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
| id | select_type | table | type | possible_keys | key    | key_len | ref         | rows | Extra                             |
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
|  1 | SIMPLE      | t     | ref  | t_idx1,t_idx2 | t_idx1 | 10      | const,const |   10 | Using where with pushed condition |
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
1 row in set (0.00 sec)

mysql> explain select id from t where e=2781 and p=23927 and ff='2010-04-29 20:31:10';
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
| id | select_type | table | type | possible_keys | key    | key_len | ref         | rows | Extra                             |
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
|  1 | SIMPLE      | t     | ref  | t_idx1,t_idx2 | t_idx1 | 10      | const,const |   10 | Using where with pushed condition |
+----+-------------+-------+------+---------------+--------+---------+-------------+------+-----------------------------------+
1 row in set (0.00 sec)
[25 Oct 2016 16:03] MySQL Verification Team
Cannot reproduce this with any of the modern releases.