Tuesday, December 14, 2010

MySQL bug and Optimization of nested query

There is strange bug in MySQL, it does not use primary key, if the value is NULL. Instead it do full table scan. Here is an example.
Copy / Paste this in text editor to see the correct post.

MariaDB [gateway]> explain select * from crontab where id = (select crontab from items where id = 19465650);
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
|  1 | PRIMARY     | crontab | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
|  2 | SUBQUERY    | items   | const | PRIMARY       | PRIMARY | 4       |       |    1 |       |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
2 rows in set (0.00 sec)


MariaDB [gateway]> explain select * from crontab where id = (select crontab from items where id = @id);
+----+----------------------+---------+------+---------------+------+---------+------+---------+-----------------------------------------------------+
| id | select_type          | table   | type | possible_keys | key  | key_len | ref  | rows    | Extra                                               |
+----+----------------------+---------+------+---------------+------+---------+------+---------+-----------------------------------------------------+
|  1 | PRIMARY              | crontab | ALL  | NULL          | NULL | NULL    | NULL | 3854804 | Using where                                         |
|  2 | UNCACHEABLE SUBQUERY | NULL    | NULL | NULL          | NULL | NULL    | NULL |    NULL | Impossible WHERE noticed after reading const tables |
+----+----------------------+---------+------+---------------+------+---------+------+---------+-----------------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [gateway]> explain
select
   *
from
   crontab,
   items
where
   items.crontab = crontab.id and
   items.id      = @id;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.00 sec)

No comments: