[MDEV-13897] SELECT @a := MAX(col) FROM t requires full index scan Created: 2017-09-23  Updated: 2020-08-25  Resolved: 2017-09-27

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 10.0, 10.1, 10.1.24, 10.2.9, 10.2
Fix Version/s: 10.1.28, 10.2.10

Type: Bug Priority: Critical
Reporter: Valerii Kravchuk Assignee: Sergei Golubchik
Resolution: Fixed Votes: 1
Labels: None


 Description   

MariaDB 10.1.x and 10.2.x do not apply " Select tables optimized away" optimization when MAX(col) value is assigned to a user variable. Consider the following primitive test case:

openxs@ao756:~/dbs/maria10.2$ bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.2.9-MariaDB Source distribution
 
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
MariaDB [test]> create table test(a int, key(a));
Query OK, 0 rows affected (0.32 sec)
 
MariaDB [test]> insert into test values (1), (2), (3);
Query OK, 3 rows affected (0.14 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
MariaDB [test]> explain select max(a) from test;
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)
 
MariaDB [test]> explain select @a := max(a) from test;
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | test  | index | NULL          | a    | 5       | NULL |    3 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
 
MariaDB [test]> explain select max(a) into @a from test;
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

Note that SELECT MAX(col) INTO @a FROM t is NOT affected.

With any large table this leads to huge difference in query execution time, as full index scan is slow.

Upstream MySQL 5.6.x is also not affected:

mysql> create table test(a int, key(a));
Query OK, 0 rows affected (0.70 sec)
 
mysql> insert into test values (1), (2), (3);
Query OK, 3 rows affected (0.26 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> explain select max(a) from test;
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows
 | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL
 | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
1 row in set (0.12 sec)
 
mysql> explain select @id := max(a) from test;
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows
 | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL
 | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+------------------------------+
1 row in set (0.02 sec)
 
mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `a` int(11) DEFAULT NULL,
  KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.03 sec)
 
mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.29-log |
+------------+
1 row in set (0.04 sec)



 Comments   
Comment by Elena Stepanova [ 2017-09-23 ]

Reproducible on 10.x, not reproducible on MariaDB 5.5 or MySQL 5.x.

Comment by Hartmut Holzgraefe [ 2017-09-26 ]

Reproducible starting with 10.0.5, 10.0.4 wasn't affected yet ....

Comment by Hartmut Holzgraefe [ 2017-09-27 ]

I tried to manually bisect this, and the change first appeared with https://github.com/MariaDB/server/commit/76e2fe0f661194ae6f6a71c2943646e25de2dd75 ... which is strange as that's just a merge commit, so the actual change should already have happened in one of the actual changesets earlier in the git log history?

Generated at Thu Feb 08 08:09:13 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.