[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 418
  • Last Modified:

Insert occassionally *very* slow, indexes may be problem

I have an INSERT statement running at a customer site that is giving me problems.

It will happen in milliseconds several times, then the next time take a couple minutes, then several in milliseconds -- followed by one that takes nearly an hour!

It's an INSERT ... (SELECT ... from TableA ...join ... join ... join)

Last month I added an index on TableA to better cover its WHERE clause & joins, and the problem was solved.

Yesterday I got the complaint again.  So I rebuilt the index I had created. No better. I updated stats on the table. No better. I rebuilt all indexes and updated all stats. No better.

The INSERT being within a trigger, it's a little hard to analyze exactly ... so for purposes of reviewing the execution plan I substituted the table into which I'm inserting for the INSERTED table.  I think that is valid ... but it is something I've changed.

The execution plan shows 80% of the time being taken to prepare the inserts into 4 indexes on the table into which we're inserting.

I suspected that meant we had a disk writing bottleneck ... but decided to check a few performance indicators ... which found the disk at 100% idle most of the time with a 0-length queue most of the time.  That doesn't sound like a bottle-neck.

I tested moving the problem indexes into a separate filegroup on a different physical disk ... but the execution plan made it look like that was no better.  And again, my disk performance indicators look OK.

What do you recommend I do to try to regain performance?

Thanks!
IndexInsertProblem.jpg
0
Daniel Wilson
Asked:
Daniel Wilson
  • 5
  • 3
  • 2
2 Solutions
 
Mohit VijayCommented:
Are you using with(nolock) or With(ReadPast) i.e. SQL Hints with your Select Statement.

like

Select A, B, C from ABC with (NOLOCK)

OR

Select A, B, C from ABC with (ReadPast)
0
 
Mohit VijayCommented:
You should use them, if not using.
0
 
LCSandman8301Commented:
are you reading from the table you are inserting to? this could cause the table spools.
check out scary dba's article about the table spool
http://scarydba.wordpress.com/2009/09/09/spools-in-execution-plans/
it seems like the select portion of this insert is probably the portion that is causing you issues.
so i would suggest seeing what you can do to make the actual insert simpler. maybe doing the logical portion ahead of time. but without actually seeing a similar version of the query that's the best i can tell you
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Daniel WilsonAuthor Commented:
I got a marginal improvement with a switch from RIGHT JOIN to WHERE NOT EXISTS.

So here's a fragment of the query:

Yes, I'm selecting from the table ... just to be sure I'm not inserting duplicates.  (This is an ETL system and orders are imported and re-imported, so eliminating duplicates is absolutely essential.)

Not using any hints at this point ... will try ...

Insert INTO SODetail (...)
(SELECT ...
From  SODEtail_Import INS 
Where 
 Not Exists (Select ID from SODetail S Where 
S.Ord_Num = INS.Ord_num AND 
dbo.PadSuffix(s.WO_Suf) = dbo.PadSuffix(INS.WO_Suf) AND

S.Download_Seq = INS.Download_Seq AND
S.DeleteME = 0
And S.Other = INS.Other )
)

Open in new window

0
 
Daniel WilsonAuthor Commented:
with (NOLOCK) is in place now ... not sure whether it's helping.

I would have thought it was the SELECT portion too, but doesn't the execution plan indicate  that it's a matter of writing the indexes that's a problem?
0
 
LCSandman8301Commented:
the table spools are showing that you are writing to indexes that you are currently using. so it would be harder to write and update an index if it is currently in use.
and usually if you make one part of your query quicker it will help accross the board.
and in this case if you speed up how it reads the data it is importing. then it will speed up the writing of this data too. i have not yeat looked at your query but will be getting to it soon
0
 
LCSandman8301Commented:
it might just be me and i've never spent the time to look into it but many times what i will do is create a primary key from the data and do a not in rather than a not exists

for example

select *
from table
where col1+':'+col2+':'+col3 not in
(
  select col1match+':'+col2match+':'+col3match
  from matchtable with (nolock)
)

if nothing else you won't be using the same table so many in the query.
i hope that helps
0
 
Daniel WilsonAuthor Commented:
It does seem I was overlooking something.  I saw 4 similar branches showing 2% + 18% each ... so thought they combined for 80% of the query.

There is, however, a SORT preparatory to a CLUSTERED INDEX insert that is taking 79% by itself.

ClusteredIndexInsert.jpg
0
 
Daniel WilsonAuthor Commented:
Upon changing that index to NONclustered, the plan changes significantly and the overall cost drops about 70%.

ChangeToNonClustered.jpg
0
 
Daniel WilsonAuthor Commented:
Well, this one took a variety of tactics ... concluding with a purge of some ancient and abandoned data.

So ... some of it did go back to the SELECT part of the query.

Thanks to both of you for your suggestions.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 5
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now