[MDEV-7885] EXPLAIN shows wrong info for ORDER BY query Created: 2015-03-30  Updated: 2016-04-17  Resolved: 2016-04-17

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 10.0, 10.1
Fix Version/s: 10.2.0

Type: Bug Priority: Major
Reporter: Sergei Petrunia Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: order-by-optimization


 Description   

EXPLAIN output doesn't match query execution for a query.

create table ten(a int);
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table one_k(a int);
insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
 
create table t2 (key1 int, col1 int, key(key1));  
insert into t2 select a,a from ten;
insert into t2 select 15,15 from one_k;
alter table t2 add key2 int, add key(key2);

explain 
select * from t2 ignore index for order by (key1) where col1<0 order by key1 limit 10;
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | t2    | index | NULL          | key1 | 5       | NULL |   10 | Using where |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+

This looks odd - why does the optimizer use index key1 when we have explicitly specified *ignore index for order by (key1)* ?

Let's run the SELECT itself:

MariaDB [j2]> flush status;
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [j2]> select * from t2 ignore index for order by (key1)  where col1<0 order by key1 limit 10;
Empty set (0.03 sec)
 
MariaDB [j2]> show status like '%sort%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| Sort_merge_passes         | 0     |
| Sort_priority_queue_sorts | 1     |
| Sort_range                | 0     |
| Sort_rows                 | 0     |
| Sort_scan                 | 1     |
+---------------------------+-------+
5 rows in set (0.01 sec)

It shows that the query did use filesort.



 Comments   
Comment by Sergei Petrunia [ 2015-03-30 ]

The reason for this is that the choice whether to use an index is made by two different pieces of code (one for EXPLAIN, another one for SELECT).

EXPLAIN uses this code in JOIN::exec_inner():

  if (select_options & SELECT_DESCRIBE)
  {
  ...
    bool made_call= false;
    if (order && 
        (order != group_list || !(select_options & SELECT_BIG_RESULT)) &&
	(const_tables == table_count ||
 	 ((simple_order || skip_sort_order) &&
	  (made_call=true) &&
          test_if_skip_sort_order(&join_tab[const_tables], order,
				  select_limit, 0, 
                                  &join_tab[const_tables].table->
                                    keys_in_use_for_query))))
      order=0;

SELECT uses this in create_sort_index:

  /*
    When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
    and thus force sorting on disk unless a group min-max optimization
    is going to be used as it is applied now only for one table queries
    with covering indexes.
  */
  if ((order != join->group_list || 
       !(join->select_options & SELECT_BIG_RESULT) ||
       (select && select->quick &&
        select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) &&
      test_if_skip_sort_order(tab,order,select_limit,0, 
                              is_order_by ?  &table->keys_in_use_for_order_by :
                              &table->keys_in_use_for_group_by))
  {

The create_sort_index() call is the second one made from JOIN::exec_inner.

Comment by Sergei Petrunia [ 2015-04-16 ]

Checked on MySQL 5.7: they correctly return "Using filesort"

Comment by Sergei Petrunia [ 2016-04-17 ]

This was fixed as part of MDEV-8646 and related fixes

Generated at Thu Feb 08 07:23:00 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.