Jones03 Jones03 - 1 month ago 8
MySQL Question

MariaDB 10.1 Order By + Limit inconsistencies

When running an order by query with a limit on MariaDB 10.1.18, I get back a wrong order.

Observe the query without the LIMIT statement:

select advert_id, published, id from vacancies order by published asc;

+-----------+-----------+----+
| advert_id | published | id |
+-----------+-----------+----+
| 328377 | 0 | 70 |
| 328844 | 0 | 80 |
| 325263 | 0 | 41 |
| 325774 | 0 | 40 |
| 325775 | 0 | 39 |
| 325929 | 0 | 38 |
| 325885 | 0 | 37 |
| 325901 | 0 | 36 |
| 325920 | 0 | 35 |
| 325917 | 0 | 34 |
| 325922 | 0 | 33 |
| 325889 | 0 | 32 |
| 325927 | 0 | 31 |
| 325238 | 0 | 43 |
| 325244 | 0 | 45 |
| 328365 | 0 | 71 |
| 328446 | 0 | 72 |
| 328362 | 0 | 68 |
| 323602 | 0 | 55 |
| 324250 | 0 | 54 |
| 324254 | 0 | 53 |
| 324911 | 0 | 52 |


With the LIMIT statement:

select advert_id, published, id from vacancies order by published asc limit 10;

+-----------+-----------+----+
| advert_id | published | id |
+-----------+-----------+----+
| 327830 | 0 | 1 |
| 326865 | 0 | 18 |
| 327328 | 0 | 9 |
| 326877 | 0 | 16 |
| 326783 | 0 | 21 |
| 326779 | 0 | 17 |
| 326774 | 0 | 15 |
| 326864 | 0 | 20 |
| 326788 | 0 | 14 |
| 326767 | 0 | 19 |
+-----------+-----------+----+


The order by on published is different in both queries.

For comparison, I ran the same queries on MariaDB 5.5.50 and found the order by + limit correctly returns the same result as the order by query. So from what I understand is that this issue is MariaDB specific, and only exists on newer versions.

Additionally I also ran the same queries, but ordering on a varchar field with a lot of different values, in that case the order was correct. So I'm thinking the problem only applies to ordering with limit on a field that has a lot of the same values.

Does anyone know if there is a way around this? Perhaps a setting in MariaDB?

FYI:

Table structure:

+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| advert_id | int(11) | YES | | NULL | |
| published | tinyint(1) | NO | | 0 | |
| (other fields omitted)


Explain on query:

explain select advert_id, published, id from vacancies order by published asc;
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | vacancies | ALL | NULL | NULL | NULL | NULL | 52 | Using filesort |
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+

explain select advert_id, published, id from vacancies order by published asc limit 10;
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | vacancies | ALL | NULL | NULL | NULL | NULL | 52 | Using filesort |
+------+-------------+-----------+------+---------------+------+---------+------+------+----------------+


Version with order by issue:

mysql Ver 15.1 Distrib 10.1.18-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2


Version without order by issue:

mysql Ver 15.1 Distrib 5.5.50-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

Answer

You do not specify which ten first rows you want to obtain. As there are a lot of rows for which published equals 0 MariaDB is free to choose some of them. If you want a specific order try:

SELECT advert_id, published, id FROM vacancies ORDER BY published asc, id LIMIT 10;