我有一个脚本,其中包含多个写入临时表的查询。每个查询都建立在前一个查询的基础上,通过获取前一个查询的结果并对其进行其他处理。写入#Data2
后,脚本将在1秒内运行。
在写入#Data2
的查询之后的下一个查询根据称为@show
的用户参数有条件地选择要显示的列。当我有条件地仅选择1列(请参见下文)时,此过程将在大约1秒钟内完成。
select
(case when 1 in (select use_object from dbo.DelimitedSplit8K(@show,','))
then d.vend_num
else null
end) vend_num
into
#Show
from
#Data2 d
但是,当我对53列进行此操作时,查询执行时间变为1分39秒(请参见下文)。为什么是这样?从理论上讲,查询应仅决定是否包含该列。为什么这在计算上会很昂贵?
select
(case when 1 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.vend_num else null end) vend_num
, (case when 2 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.terms_code else null end) terms_code
, (case when 3 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.last_purch else null end) last_purch
, (case when 4 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.purch_ytd else null end) purch_ytd
, (case when 5 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pay_ytd else null end) pay_ytd
, (case when 6 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.vend_remit else null end) vend_remit
, (case when 7 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.curr_code else null end) curr_code
, (case when 8 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.bank_code else null end) bank_code
, (case when 9 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pay_type else null end) pay_type
, (case when 10 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pur_acct else null end) pur_acct
, (case when 11 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.vendname else null end) vendname
, (case when 12 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.fax_num else null end) fax_num
, (case when 13 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.telex_num else null end) telex_num
, (case when 14 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pay_hold else null end) pay_hold
, (case when 15 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pay_hold_date else null end) pay_hold_date
, (case when 16 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.pay_hold_reason else null end) pay_hold_reason
, (case when 17 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.sitename else null end) sitename
, (case when 18 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.siteaddress else null end) siteaddress
, (case when 19 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.city else null end) city
, (case when 20 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.state else null end) state
, (case when 21 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.zip else null end) zip
, (case when 22 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.county else null end) county
, (case when 23 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.country else null end) country
, (case when 24 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.FSMAApproved else null end) FSMAApproved
, (case when 25 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.FSMAAuditDatetime else null end) FSMAAuditDatetime
, (case when 26 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.FSMAAuditEditor else null end) FSMAAuditEditor
, (case when 27 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.vend_seq else null end) vend_seq
, (case when 28 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.interaction_id else null end) interaction_id
, (case when 29 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.interaction_stat else null end) interaction_stat
, (case when 30 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.topic else null end) topic
, (case when 31 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.Uf_CheckLevel else null end) Uf_CheckLevel
, (case when 32 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.approbation_type else null end) approbation_type
, (case when 33 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.submitted_date else null end) submitted_date
, (case when 34 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.approver else null end) approver
, (case when 35 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.approval_date else null end) approval_date
, (case when 36 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.rejector else null end) rejector
, (case when 37 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.rejection_date else null end) rejection_date
, (case when 38 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.vendstat else null end) vendstat
, (case when 39 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.po_num else null end) po_num
, (case when 40 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.po_orderdate else null end) po_orderdate
, (case when 41 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.po_stat else null end) po_stat
, (case when 42 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.po_invnum else null end) po_invnum
, (case when 43 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.po_invdate else null end) po_invdate
, (case when 44 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.poi_line else null end) poi_line
, (case when 45 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.poi_release else null end) poi_release
, (case when 46 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.poi_item else null end) poi_item
, (case when 47 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.poi_stat else null end) poi_stat
, (case when 48 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.qty_ordered else null end) qty_ordered
, (case when 49 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.qty_received else null end) qty_received
, (case when 50 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.due_date else null end) due_date
, (case when 51 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.rcvd_date else null end) rcvd_date
, (case when 52 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.poi_itemdesc else null end) poi_itemdesc
, (case when 53 in(select use_object from dbo.DelimitedSplit8K(@show,',')) then d.u_m else null end) u_m
into #Show
from
#Data2 d
答案 0 :(得分:2)
您可以以更简单的方式执行此操作,而无需涉及另一个临时表,也无需调用此昂贵的函数53次:
DECLARE @show varchar(255) = '1,3';
SELECT vend_num = MIN(CASE y.value WHEN 1 THEN d.vend_num END),
terms_code = MIN(CASE y.value WHEN 2 THEN d.terms_code END),
last_purch = MIN(CASE y.value WHEN 3 THEN d.last_purch END)--,
-- ...
FROM #Data2 AS d
OUTER APPLY dbo.DelimitedSplit8K(@show,',') AS y;
我当然同意上面的评论,您应该考虑table-valued parameters而不是传递逗号分隔的字符串;那么您可以加入对抗TVP的行列,而不必进行任何昂贵的拆分。
如果您真的很喜欢使用函数,则应查看其中几个拆分函数的性能测试,并考虑采用更好的替代方法(请参见this和this)。
在SQL Server 2016(和Azure SQL数据库)中,您将能够使用STRING_SPLIT()
,这是令人惊讶的性能出色的本机选项。参见this,this,this和this。