2012-01-26 65 views
0


 我一直在尝试在MySQL中优化一个尴尬的ORDER BY。问题是我希望NULL和空白字段''出现在底部而不是顶部。我想出了:MySQL ORDER BY优化时排序NULL和''最后 - 是否有可能?

ORDER BY isnull(if (isnull(Lastname) OR ascii(Lastname)=0, null, 1)), Lastname ASC, 
isnull(if (isnull(Firstname) OR ascii(Firstname)=0, null, 1)), Firstname ASC; 

但是,这是造成文件排序,访问所有的表中的行:(

通过创建(姓氏,名字)的指数我能优化查询快速用一个简单的排序可以减轻:

ORDER BY Lastname ASC, Firstname ASC; 

号文件排序:)

看来,MySQL不会让你改变默认的排序为空值,并且没有NULLS LAST选项。我不可能优化原始排序吗?

在此先感谢

+0

这只适合有人提供可行的解决方案 – Cosmicnet 2012-01-27 01:58:17

回答

1

此解决方法如何?

(SELECT * FROM 
    WHERE Lastname IS NOT NULL AND Firstname IS NOT NULL 
    ORDER BY Lastname ASC, Firstname ASC) 
UNION 
(SELECT * FROM 
    WHERE Lastname IS NULL OR Firstname IS NULL 
    ORDER BY Lastname ASC, Firstname ASC); 

如果上面的查询速度太慢,那么它必须需要一个新的参考列 - 像hasnull - 使排序更快。该列将在插入或更新时更新。使用hasnull, Lastname, Firstname创建一个索引并将其用于排序。

+0

不幸的是,这需要更长的时间。该表有很多行。尽管在派生表中有两种类型的代码很快,但联盟本身很慢:( – Cosmicnet 2012-01-27 05:23:53

+0

我又增加了一个建议,对于你的失望感到抱歉:( – lqez 2012-01-27 05:29:35

+0

)不幸的是代码库很大,需要添加一列的前景虽然你的第一个建议实际上导致了解决方案的实现,但忘记联合,只是将它作为2个独立的查询来完成,使用适当的多键索引,两个查询都会在一秒之内返回即使是在大桌子上,也不要回答我自己的问题,你想用这个更新你的回答吗?那么我会接受它作为解决方案:) – Cosmicnet 2012-01-27 18:06:29

0

你有没有考虑连接名字和姓氏列,然后排序两者的组合?

mysql> select *, CONCAT_WS(' ', fname, lname) as fullname from order_by_neg_test order by fullname desc; 

+----+-------+-------+---------+--------------+ 
| id | value | fname | lname | fullname  | 
+----+-------+-------+---------+--------------+ 
| 4 | -1 | mike | purcell | mike purcell | 
| 3 |  0 | NULL | jenkins | jenkins  | 
| 5 | 17 | chris | NULL | chris  | 
| 1 | 45 | NULL | NULL |    | 
| 2 |  1 | NULL | NULL |    | 
| 6 | 27 |  | NULL |    | 
| 7 | -1 | NULL | NULL |    | 
+----+-------+-------+---------+--------------+ 
7 rows in set (0.00 sec) 
+0

这有一个很好的输出。但它是一个文件并且很慢。 – Cosmicnet 2012-01-27 18:01:52

+0

你真的有行的名字和姓氏可以为空?也许你应该在传递到数据库之前实施更严格的数据验证。您可以尝试使用DESC与ASC,因为DESC会将空值推入底部。 – 2012-01-27 18:09:28

+0

我已经完成了列不为空的测试。它仍然采用文件夹方式,因为您需要使用字符串函数将空字符串以ASC排序的形式放到底部。唯一认为我发现快速有效的是具有适当的多键索引的多查询解决方案。 – Cosmicnet 2012-01-27 20:31:57