8

Setting

In a datawarehouse, I am joining a fact table to 20 dimensions. The fact table has 32 million rows and 30 columns. This is a temporary staging table so I don't have to deal with other users reading or writing to the table. I select 10 columns from the base table and 20 columns from the respective dimensions. The dimension tables are small (between 3 and 15.000 rows). The fields on which are joined are both integers and nvarchars. I use a SELECT ... INTO statement. There are no indexes on the tables.

The execution speed of this query is too slow to be useful.

Tried-out solutions

Because the query takes too long to process, I tried out following solutions:

  1. Split the 20 joins into 4 joins on 5 tables. The query performance remains low however.
  2. Put indexes on the foreign key columns. No significant time decrease.
  3. Make sure the fields of the join condition are integers. I noticed a performance increase of 25%. Not quite what I am searching for.
  4. Use an insert into statement instead of select into. Worse performance because of log file growth although the database is in simple recovery mode.

These findings led me to including the actual execution plan which shows that 89% of the cost lies in the table insert. The other costs are 8% table scan on the fact table and 2% on hash matching for the inner joins.

Questions

  1. What are the possible reasons of the slow table insert?
  2. What are ways to identify this bottleneck without the execution plan?
  3. What actions can I take to reduce the cost of the table insert?
  • SELECT INTO is about the fastest insert DML method there is. What throughput are you getting in rows/sec and MB/sec? Maybe it is simply near the expected maximum. What server version is this? – usr Dec 3 '14 at 11:34
  • The percentages in actual plan are estimates, not the actual percentages. Using "statistics io" might reveal something important. – James Z Dec 3 '14 at 15:38
12

What are the possible reasons of the slow table insert? What are ways to identify this bottleneck without the execution plan?

Read How to analyse SQL Server performance, specially the part about Analyzing individual query execution wait times.

What actions can I take to reduce the cost of the table insert?

That would depend largely on the result of the performance analysis. First and foremost, ensure the SELECT part is as fast as possible. Assuming that problem is the single threaded fully logged insert, some solutions are:

  • Also check for internal and external fragmentation if lots of spread out rows are first deleted from the table. – Ian Ringrose Dec 3 '14 at 17:08
1

Below is my experience and might help anyone else out there.

We were trying to transfer some data from one database to another also doing some transformations in the way. Testing the transformation we were doing a lot of inserts, fixing things along the way then delete in order to test the insert again. However after some inserts and truncates our queries started running slow and one simple insert started taking up to 9mins while previously it was running for around 3mins.

  1. Well we started looking at optimising SELECTs first. Instead of subqueries we used #tempTables. While this did speed things a bit it was still not satisfatory.
  2. What made all the diference was and index rebuild and a statistics update on the destination database and that brought the insert into around 2mins.

So try these two strategies and see how this works out for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.