I'm trying to hack a FLOSS application called Phabricator / Phorge
Let's take this simple MySQL table storing some questions by ID and their status (open, closed, invalid etc.):
CREATE TABLE `ponder_question` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
KEY `status` (`status`),
I want to order by a specific status first, then the others. So:
SELECT * FROM ponder_question
ORDER BY status='open' DESC
LIMIT 5
It works but consider this DESCRIBE. That query is apparently examining 5000 rows which is probably too much / it is doing a full table scan:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | ponder_question | NULL | index | NULL | status | 130 | NULL | 5000 | 100.00 | Using index; Using filesort |
(Instead, if you EXPLAIN a simple ORDER BY status DESC LIMIT 5 it examines just 5 rows)
To reduce the number of examined rows and avoid that Using filesort I also tried a FORCE INDEX:
SELECT * FROM ponder_question
FORCE INDEX (status)
ORDER BY status='open' DESC
LIMIT 5
I tested in MySQL 5.7 and MariaDB 10.3. Anyway, my question is not version-specific.
I guess I need to avoid this approach.
I maybe need to change the schema to have a simpler ordering clause, but maybe not.
To be honest, the final goal is to ORDER BY status='open' DESC, id, so showing all open questions by creation, and then all closed questions by creation.
I think this approach is bad, but I was just trying to be nice with this application, without proposing a schema change. So feel free to tell me that my question is stupid:
Question: how do you implement an order by a value first, in a more efficient way?
Some related similar approaches that apparently do not describe this problem: