包含 GROUP BY 子句的语句中的 UDAF 性能
如果调用 UDAF 的 SQL 语句还包含 GROUP BY 子句,该 UDAF 的性能可能会低于预期。例如:
=> SELECT a, MYUDAF(b) FROM sampletable GROUP BY a;
在类似于以上示例的语句中,Vertica 不会在调用 UDAF 的 aggregate()
方法之前将行数据合并到一起。相反,它会为每个数据行调用 aggregate()
一次。通常,让 Vertica 合并行数据的开销超过为每个数据行调用 aggregate()
的开销。但是,如果 UDAF 的 aggregate()
方法具有很大开销,您可能会发现 UDAF 的性能受到影响。
例如,假设内存由 aggregate()
分配。在包含 GROUP BY 子句的语句中调用此方法时,此方法将为每个数据行执行该内存分配。因为内存分配是一个成本相对高昂的过程,所以此分配会影响 UDAF 和查询的总体性能。
有两种方法可用于解决包含 GROUP BY 子句的语句中的 UDAF 性能问题:
-
减少对
aggregate()
的每个调用的开销。如果可能,将任何分配或其他设置操作移到 UDAF 的setup()
函数。 -
声明一个特殊参数,以指示 Vertica 在调用 UDAF 时将行数据分组到一起。下文介绍此技术。
使用 _minimizeCallCount 参数
UDAF 可以指示 Vertica 始终将行数据分组到一起,以减少对其 aggregate()
方法调用的次数。要触发此行为,UDAF 必须声明一个名为 _minimizeCallCount
的整数参数。您不需要在 SQL 语句中为此参数设置值。如果 UDAF 声明此参数,将触发 Vertica 在调用 aggregate()
时将行数据分组到一起。
声明 _minimizeCallCount
参数的方法与声明其他 UDx 参数相同。有关详细信息,请参阅UDx 参数。
重要
在实施_minimizeCallCount
参数之前和之后,始终应测试 UDAF 的性能,以确保提高性能。您可能会发现让 Vertica 为 UDAF 分组行数据的开销超过重复调用 aggregate()
的成本。