Search code examples
mysqlsqlperformancedatabase-performance

MySQL pipelined order by seems not working


I have table user[id, name, status] with index[status, name, id]

SELECT *
FROM user
WHERE status = 'active'
ORDER BY name, id
LIMIT 50

I have about 50000 users with status == 'active'

1.) Why does MySQL explain show about 50000 in ROWS column? Why it follows all leaf nodes even when the index columns equals to order by clause?

2.) When I change order by clause to

ORDER BY status, name, id

EXTRA column of explain clause shows:

Using index condition; Using where; Using filesort

Is there any reason why it can't use index order in this query?

edit1:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `status_name_id` (`status`,`name`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

query:

SELECT *
FROM `user`
WHERE status = 'complete'
ORDER BY status, name, id
LIMIT 50

explain:

id: 1
select_type: SIMPLE
table: f_order
type: ref
possible_keys: status_name_id
key: status_name_id
key_len: 768
ref: const
rows: 50331
Extra: "Using where; Using index; Using filesort"

The weirdest thing is that if I change SELECT statement to

SELECT *, count(id)

It use index again and query is twice faster. And extra section contains only

Using where; Using index

Table contains 100k rows, 5 different statuses and 12 different names.

MySQL: 5.6.27

edit2:

Another example:

This takes 400ms (avg) and does explicit sort

SELECT *
FROM `user`
WHERE status IN('complete')
ORDER BY status, name, id
LIMIT 50

This takes 2ms (avg) and doesn't explicit sort

SELECT *
FROM `user`
WHERE status IN('complete', 'something else')
ORDER BY status, name, id
LIMIT 50

Solution

  • According to comments it is probably bug.