[MDEV-4932] query with order by on indexed column is using filesort Created: 2013-08-21  Updated: 2018-09-19  Resolved: 2015-09-07

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 5.5.32
Fix Version/s: 10.1.7

Type: Bug Priority: Major
Reporter: Patryk Pomykalski Assignee: Oleksandr Byelkin
Resolution: Cannot Reproduce Votes: 0
Labels: None

Attachments: File sort_bug.sql    
Issue Links:
Relates
relates to MDEV-17213 range optimizer costly filesort on in... Open

 Description   

CREATE TABLE `sort_bug` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `data` datetime NOT NULL,
  `t` smallint(5) unsigned NOT NULL,
  `id_region` smallint(5) unsigned NOT NULL,
  `id_miasto` smallint(5) unsigned NOT NULL,
  `typ_obiektu` smallint(5) unsigned NOT NULL,
  `o` int(10) unsigned NOT NULL,
  `c` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `KEY_data` (`data`),
  KEY `o` (`o`)
) ENGINE=InnoDB AUTO_INCREMENT=745193 DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

With a small amount of rows filesort is used instead of index scan:

explain SELECT * FROM sort_bug ORDER BY data DESC LIMIT 1;
+------+-------------+----------+------+---------------+------+---------+------+------+----------------+
| id   | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+------+-------------+----------+------+---------------+------+---------+------+------+----------------+
|    1 | SIMPLE      | sort_bug | ALL  | NULL          | NULL | NULL    | NULL |  211 | Using filesort |
+------+-------------+----------+------+---------------+------+---------+------+------+----------------+

The same is without LIMIT. Analyze table didn't help in this example.
When LIMIT is small adding a bogus WHERE clause can help:

explain SELECT * FROM sort_bug where id > 0 ORDER BY data DESC LIMIT 1;
+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+
| id   | select_type | table    | type  | possible_keys | key      | key_len | ref  | rows | Extra       |
+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+
|    1 | SIMPLE      | sort_bug | index | PRIMARY       | KEY_data | 8       | NULL |    1 | Using where |
+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+



 Comments   
Comment by Patryk Pomykalski [ 2013-08-21 ]

file with insert data

Comment by Patryk Pomykalski [ 2013-08-22 ]

In this case both costs read_time and index_scan_time are equal to 1. In test_if_cheaper_ordering() index scan is considered if the cost is strictly lower than read_time. Maybe it would be better to change < to <= ?

— sql/sql_select.cc 2013-08-21 18:27:02 +0000
+++ sql/sql_select.cc 2013-08-22 10:12:40 +0000
@@ -23535,7 +23535,7 @@
index_scan_time= select_limit/rec_per_key *
min(rec_per_key, table->file->scan_time());
if ((ref_key < 0 && (group || table->force_index || is_covering)) ||

  • index_scan_time < read_time)
    + index_scan_time <= read_time)
    {
    ha_rows quick_records= table_records;
    if ((is_best_covering && !is_covering) ||
Comment by Oleksandr Byelkin [ 2015-09-07 ]

It looks like bug is not reproducible any more on 10.1 (checked with innodb and aria).

Comment by Oleksandr Byelkin [ 2015-09-07 ]

We can not reproduce it on 10.1. But if you feel that we are wrong please reopen it.

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