写着简单跑得又快的数据库语言 SPL
select max (consecutive_day)
from (select count(*) (consecutive_day
from (select sum(rise_mark) over(order by trade_date) days_no_gain
from (select trade_date,
case when closing_price>lag(closing_price) over(order by trade_date)
then 0 else 1 END rise_mark
from stock_price ) )
group by days\_no\_gain)
这个语句的工作原理就不解释了,反正有点绕,同学们可以自己尝试一下。
SELECT TOP 10 x FROM T ORDER BY x DESC
但是,这个语句对应的执行逻辑是先对所有数据进行大排序,然后再取出前 10 个,后面的不要了。大家知道,排序是一个很慢的动作,会多次遍历数据,如果数据量大到内存装不下,那还需要外存做缓存,性能还会进一步急剧下降。如果严格按这句 SQL 体现的逻辑去执行,这个运算无论如何是跑不快的。然而,很多程序员都知道这个运算并不需要大排序,也用不着外存缓存,一次遍历用一点点内存就可以完成,也就是存在更高性能的算法。可惜的是,用 SQL 却写不出这样的算法,只能寄希望于数据库的优化器足够聪明,能把这句 SQL 转换成高性能算法执行,但情况复杂时数据库的优化器也未必靠谱。
stock_price.sort(trade_date).group@o(closing_price<closing_price[-1]).max(~.len())
计算思路和前面的 SQL 相同,但因为引入了有序性后,表达起来容易多了,不再绕了。
T.groups(;top(-10,x))
SPL 有更丰富的集合数据类型,容易描述单次遍历上实施简单聚合的高效算法,不涉及大排序动作。
评论