我有两个查询,将逗号分隔的列表分成几行并插入表变量中。
对于第一个查询,我使用了自定义函数:
用户定义的Spilt函数。
Create FUNCTION [dbo].[Split_S]
(
@sInputList VARCHAR(MAX)
,@sDelimiter VARCHAR(8)
)
RETURNS @List TABLE ([item] VARCHAR(8000))
AS
BEGIN
DECLARE @sItem VARCHAR(MAX)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
BEGIN
SELECT
@sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1)))
,@sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))
IF LEN(@sItem) > 0
INSERT INTO @List SELECT @sItem
END
IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @sInputList-- Put the last item in
RETURN
END
查询1:
DECLARE @F TABLE(F BIGINT)
INSERT INTO @F
SELECT [item] FROM [dbo].[Split_S]
(N'82,13,51,68,6',',')
查询2:
DECLARE @F2 TABLE(F BIGINT)
INSERT INTO @F2
SELECT Value
from
STRING_SPLIT(N'82,13,51,68,6',',')
两个查询的查询计划
为什么37%并使用STRING_SPLIT其63%。 但是,如果我只比较select语句,则STRING_SPLIT的查询费用为1%。
哪个查询具有更好的性能,为什么?
答案 0 :(得分:0)
如果仅检查查询中包含选择查询的部分,那么根据执行计划(EP),使用STRING_SPLIT会获得更好的性能。结果将是99%和1%。
但是,当我们使用STRING_SPLIT函数返回的数据(例如“ select ... into”或在您的情况下为“ insert ... select”)时,您可能会注意到服务器使用“ table spool(Eager Spool)”。此运算符将这些行取并将它们存储在tempdb数据库中存储的隐藏临时对象中(使用此逻辑的想法是可以重新使用假脱机的数据后台打印程序一次从上一个运算符获取 ALL 行,这意味着这是“ 阻塞运算符”。