Link to home
Start Free TrialLog in
Avatar of Daniel Wilson
Daniel WilsonFlag for United States of America

asked on

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
SOLUTION
Avatar of Mohit Vijay
Mohit Vijay
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You should use them, if not using.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Daniel Wilson

ASKER

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

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?
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
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
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
Upon changing that index to NONclustered, the plan changes significantly and the overall cost drops about 70%.

ChangeToNonClustered.jpg
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.