假设我有这个查询(伪):
Select T.a,
T.b,
(select top 1 element from fn_split(c,',') where element=T.element)
From largeTable T
对于每一行运行fn_split
,我想使用内联表值udf,这样性能会更好。
注意:fn_split
只需通过,
但是看一下内联表值udf structure :
create FUNCTION [dbo].[fn_...]
(
...
)
RETURNS table
AS
RETURN SELECT ...(!!!)
它应该立即返回选择作为第一个语句!
但是,如果我的UDF看起来像:
CREATE FUNCTION [dbo].[FN_Split]
(
@InDelimitedString varchar(max),
@InDelimiter varchar(10)
)
RETURNS
@tblArray TABLE
(
ElementID smallint IDENTITY(1,1),
Element varchar(1000)
)
AS
BEGIN
DECLARE @StrPos smallint,
@StrStart smallint,
@DelimiterLength smallint
SET @DelimiterLength = LEN(@InDelimiter)
WHILE LEN(@InDelimitedString) > 0
BEGIN
--Removed for clarity . do some CHARINDEX manipulation ETc.
END
RETURN
END
问题:
我无法立即返回select
,但我仍想将fn_split
更改为内联表值udf。
我该怎么办?
答案 0 :(得分:4)
问题在于您的分割功能。它以RBAR方式进行拆分。您应该使用基于集合的拆分器。以下是Jeff Moden的DelimitedSplit8k,它是最快的分割器之一:
Class<? extends XXXX> toolClass = null; // Some class with assignOptions
try {
toolClass.getMethod("assignOptions", MyOptionModule.class).invoke(null, optionModule);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
// Exceptions, no options if NoSuchMethodException
}
注意:请务必查看有关更新功能的文章
有关更多分割功能,请阅读Aaron Bertrand爵士的这些文章: