Reputation: 2276
I have a script that has multiple queries that write to temporary tables. Each query builds upon the previous one by taking the results of the previous query and doing something else with it. The script runs in 1 second after writing to #Data2
.
The next query after the one that writes into #Data2
conditionally selects which columns to display based on a user parameter called @show
. When I conditionally select only 1 column (see below), this runs in about 1 second.
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
However, when I do this with 53 columns, the query execution time turns to 1 minute 39 seconds (see below). Why is this? Theoretically, the query should only be making a decision to include or to not include the column. Why would this be computationally expensive?
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
Upvotes: 0
Views: 62
Reputation: 280431
You can do this in a simpler way without involving yet another temp table and without calling this expensive function 53 times:
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;
Of course I agree with comments above that you should consider table-valued parameters instead of passing a comma-separated string; then you can just join against the TVP instead of doing any expensive splitting at all.
If you're really married to using a function, you should look at the performance tests of several of these splitting functions and maybe consider a better alternative (see this and this).
In SQL Server 2016 (and Azure SQL Database), you'll be able to use STRING_SPLIT()
, which is a surprisingly well-performing native option. See this, this, this, and this.
Upvotes: 2