我有一个sample表:
sample
NAME SIZE sam 100 skr 200 sss 50 thu 150
我想做这个查询:
select total(size) > 300 from sample;
但是我的表非常大,所以如果total(size)已经大于300,我希望它尽早停止计算total(size),而不是遍历整个表(我的表中没有负大小)。
total(size)
monwx1rj1#
我已经找到了一种方法让它提前停止,通过使用一个窗口函数,***但是***不幸的是,由于另一个原因,它使它变慢了。我希望其他人有一种方法可以做得更快。要真正使它更快,你可能需要创建一个自定义聚合函数。
像total()这样的普通聚合函数总是将所有给定的行相加,但是你可以使用聚合函数window function来只添加其中的一些行:
total()
select name, size, total(size) over (rows between unbounded preceding and current row) from sample
我会给予你
sam|100|100.0 skr|200|300.0 sss|50|350.0 thu|150|500.0
其中第三列是累计和。在此结果中,您可以看到,一旦看到350,您就希望停止此查询。您可以通过将上述查询放入子查询并使用EXISTS运算符来完成此操作:
350
EXISTS
select exists( select 1 from (select total(size) over (rows between unbounded preceding and current row) as total_size from sample) where total_size > 300)
这会将查询过滤到大于300的行,然后在找到其中一行后立即停止并返回true(1),如果找不到具有该和的行,则返回false(0)。
true
1
false
0
**但是:**此版本可能需要更长的时间,而不仅仅是
select total(size) > 300 from sample
因为它会重新计算每行的总和,而不是将下一行的大小添加到运行总和中。
1条答案
按热度按时间monwx1rj1#
我已经找到了一种方法让它提前停止,通过使用一个窗口函数,***但是***不幸的是,由于另一个原因,它使它变慢了。我希望其他人有一种方法可以做得更快。要真正使它更快,你可能需要创建一个自定义聚合函数。
窗函数法
像
total()
这样的普通聚合函数总是将所有给定的行相加,但是你可以使用聚合函数window function来只添加其中的一些行:我会给予你
其中第三列是累计和。在此结果中,您可以看到,一旦看到
350
,您就希望停止此查询。您可以通过将上述查询放入子查询并使用EXISTS
运算符来完成此操作:这会将查询过滤到大于300的行,然后在找到其中一行后立即停止并返回
true
(1
),如果找不到具有该和的行,则返回false
(0
)。**但是:**此版本可能需要更长的时间,而不仅仅是
因为它会重新计算每行的总和,而不是将下一行的大小添加到运行总和中。