tags:

views:

28

answers:

3

Hello fellow experts,

I have a huge table and I want simple sorting.

It could be so easy. I could just create an index and do some really fast sorting thanks to that index.

But my client wants to put NULLs to the end, which is complicates the whole situation.

Instead of simple: SORT BY name ASC I have to do SORT BY name IS NULL ASC, name ASC. That would be ok, but it because of that my index is useless, and the sorting is very slow.

I don't know if there's a way to solve this problem, but if there is one, I desperately ask for help. :'(

A: 

perhaps, instead of null you could give it an arbitrary value, like 'a'. im not an expert on this but that might work?

Rob
A: 

Use a union to first select those records where name is not null, and then the rest.

klausbyskov
Thanks, that makes sense, I'm gonna try it!
Vojto
+3  A: 

UNION ALL is not guaranteed to preserve the record order, but with current implementation the final ORDER BY will amount just to a single pass over already ordered fields:

SELECT  *
FROM    (
        SELECT  1 AS source, *
        FROM    user
        WHERE   name IS NOT NULL
        ORDER BY
                name
        )
UNION ALL
SELECT  2 AS source, *
FROM    user
WHERE   name IS NULL
ORDER BY
        source, name

Omitting the final ORDER BY may break your application in the future.

This is probably one of the rare cases when it's better to split the query in two on the client side.

Quassnoi
Ok, just a question. Is this safe when you have like 1M records? Because I just tried it with 1M records and I always had to cancel the query, never reached result.Could it be that first query loads too much, shouldn't I pass it some LIMITE?
Vojto
@Vojto: MySQL caches the results of the inline views internally. You better use two queries on the client side. BTW, do you really need to retrieve all `1M` records?
Quassnoi
Well, I am putting limit at the end of whole query, but when I don't put limit on those sub-queries it's very slow.
Vojto
@Vojto: put the `LIMIT` into the both subqueries **and** into the end.
Quassnoi