SQL Server: Strange execution plan -


i have etl code running on sql server 2008 standard. relatively small number of rows (~50,000) processed , loaded temp table. execute insert query copy on rows not present in larger table (~1,000,000+ rows). temp table contains same primary key , clustered index destination table.

create table #newclaims(extractdate datetime, sitename nvarchar(50), sitecd nvarchar(50), contracttypecd nvarchar(50),  claimratetype nvarchar(50), claimratetypecd nvarchar(50), claimstatus nvarchar(50), claimstatuscd nvarchar(50),  creationdt datetime, statusdt datetime, claimid nvarchar(50), seqnum int, creationuserid nvarchar(50),  specialclaimind nvarchar(50), jobseekerid nvarchar(50), invoicenum nvarchar(50), jobid nvarchar(50), jobrefid int, recoveryreason nvarchar(50), claimamount money, gstamount money, approvedamount money, claimcurrencyind nvarchar(50),  employerid nvarchar(50), baseratetype nvarchar(50), baseratetypecd nvarchar(50) constraint pk_newclaims primary key clustered(claimid, claimstatuscd)); 

here sql loads temp table records target

insert dbo.claim( extractdate, sitename, sitecd, contracttypecd, claimratetype, claimratetypecd, claimstatus, claimstatuscd, creationdt,  statusdt, claimid, seqnum, creationuserid, specialclaimind, jobseekerid, invoicenum, jobid, jobseqnum, recoveryreason,  claimamount, gstamount, approvedamount, claimcurrencyind, employerid, baseratetype, baseratetypecd ) select  n.extractdate,  n.sitename, n.sitecd, n.contracttypecd, n.claimratetype, n.claimratetypecd, n.claimstatus, n.claimstatuscd,  n.creationdt, n.statusdt, n.claimid, n.seqnum, n.creationuserid, n.specialclaimind, n.jobseekerid, n.invoicenum, n.jobid,  n.jobrefid, n.recoveryreason, n.claimamount, n.gstamount, n.approvedamount, n.claimcurrencyind, n.employerid, n.baseratetype,  n.baseratetypecd #newclaims n left join dbo.claim c on n.claimid = c.claimid , n.claimstatuscd = c.claimstatuscd c.claimid null 

when run execution plan unusual. refuses utilise pk clustered index on dest table , attempts use any other index available instead. curiously uses index retreieve claimid , statuscd. if disable indexes on dest table 1 one, execution plan keep trying use other indexes until i've disabled of them except clustered, @ point gives in , uses it, produces bunch of bitmap operations. query runs faster when occurs.

i've experimented adding index hint: (index(1)). hint causes work expect, using index , running faster non hint version. forced index seek shows scalar operators in execution plan - indicate problem?

seek keys[1]: prefix: [esd4].[dbo].[claim].claimid, [esd4].[dbo].[claim].claimstatuscd = scalar operator([tempdb].[dbo].[#newclaims].[claimid] [n].[claimid]), scalar operator([tempdb].[dbo].[#newclaims].[claimstatuscd] [n].[claimstatuscd]) 

is there i'm missing? don't having force sql use specific execution plan, index hints can backfire.

update

  • recomputing table statistics didn't help
  • changing left join "where not exists" doesn't affect choice of index used, did change plan slightly. instead of hash match (left join), it's doing hash match (left anti semi join), presumably faster.

it's difficult without more information, can test this. may faster output of pk ids want insert table variable (@pkids), in update statement, use 'select ... #newclaims inner join @pkids'. it's difficult without plan , having dataset, maybe in situation help. if inner join, can use index hint pk. #newclaims table may need pk on claimid , claimstatuscd, reducing time build #newclaims.

declare @pkids table (claimid int primary key)  insert @pkids (claimid) select distinct n.claimid #newclaims n not exists (select 1 dbo.claim c c.claimid = n.claimid , n.claimstatuscd = c.claimstatuscd)  insert dbo.claim( extractdate, sitename, sitecd, contracttypecd, claimratetype, claimratetypecd, claimstatus, claimstatuscd, creationdt,  statusdt, claimid, seqnum, creationuserid, specialclaimind, jobseekerid, invoicenum, jobid, jobseqnum, recoveryreason,  claimamount, gstamount, approvedamount, claimcurrencyind, employerid, baseratetype, baseratetypecd ) select  n.extractdate,  n.sitename, n.sitecd, n.contracttypecd, n.claimratetype, n.claimratetypecd, n.claimstatus, n.claimstatuscd,  n.creationdt, n.statusdt, n.claimid, n.seqnum, n.creationuserid, n.specialclaimind, n.jobseekerid, n.invoicenum, n.jobid,  n.jobrefid, n.recoveryreason, n.claimamount, n.gstamount, n.approvedamount, n.claimcurrencyind, n.employerid, n.baseratetype,  n.baseratetypecd #newclaims n join @pkids pkids on pkids.claimid = n.claimid 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -