views:

67

answers:

2

There is a stored procedure:

 CREATE PROCEDURE [dbo].[TestProc]
 AS
 BEGIN 
     SET NOCOUNT ON;

     create table #thistable (rid char(32))
     insert into #thistable(rid)
     select A0RID from tblCdbA0 with (nolock)
  END

When the procedure is executed alone it takes 400-500 ms, but when 10 threads are executing the same procedure in parallel, then the first thread finishes in 1300 ms, the last - in 6000 ms and average is 4800 ms. As you can see there is no locking where threads wait when other finish to execute. Moreover, server CPU is loaded at less then 100%, i.e. there are enough resources in order to execute them at the same time. How could that be?

+1  A: 

why select from the same table 8 times, just duplicate the rows once you get them the first time, try this:

CREATE PROCEDURE [dbo].[TestProc]
AS
SET NOCOUNT ON;

create table #thistable (rid char(32))

;WITH AllNumbers AS
(
    SELECT 1 AS Number
    UNION ALL
    SELECT Number+1
        FROM AllNumbers
        WHERE Number<8
)
insert into #thistable
        (rid)
    select A0RID 
        from tblCdbA0               t with (nolock)
        INNER JOIN AllNumbers       a ON 1=1

RETURN 0
GO

if you do it with the UNIONs you have 8 table scans per thread, and that will adds up and affect performance.

KM
thanks for comment, basically the code is only for a demo, it's performance itself is not interesting. The question is in concurrency.
Tim
@Tim, in your question you quote specific execution times and give a specific (strange) query, yet you ask for something else? perhaps you need to revise your question but I'm not sure what you're after. Perhaps you after something less specific like @Remus Rusanu's answer. If so, do you really expect SQL Server to have unlimited read/write bandwidth to handle all of your IO (for each thread) simultaneously?
KM
+3  A: 

To start with, CPU is not the only resource in a database. The query you posted inserts into a #temp table in tempdb, which would need resources like:

  • tempdb SGAM/GAM allocation.
  • tempdb log
  • buffer pool
  • tempdb IO

So if you have 400-500 ms for one thread and 10 threads finish in 6000 ms, that doesn't surprise me. You request 10 times more work (ie. 10 times more IO to write those #temp tables onto disk), so 4000-5000 ms is expected. The extra 1000 ms could be from contention (threads competing for same resource).

Ultimately, you need to measure where is the time spent, see SQL Server 2005 Waits and Queues for a good methodology how to analyze the issue.

Remus Rusanu
If I'd venture a guess, I'd say the limiting factor is the log flush speed. One thread takes 400-500 ms because that's how much it takes to write into the LDF file the data you insert, and the statement cannot return until it commits (log is hardened on disk). So 10 threads write 10 times as much, will take 10 times more.
Remus Rusanu
the comment looks like reasonable assumption, is there a way how one can avoid writing to a log, in order to check it? In any case it is a bit strange that server is not able to write into log in parallel..
Tim
Of course the server does write in the log in parallel :) But if your HDD does 130Mb/sec max transfer (which is the usual max/perfect transfer rate of a consumer drive) then one query will use all 130 Mb/sec, 10 threads will share it and get about 13Mb/sec each.
Remus Rusanu
exactly, writing in parallel is a must.
Tim
I don't think you understand. If your **hardware** can only write 130MB/sec, then an operation that has to write 70MB will take 400ms. 10 operations will have to write 700MB and will take 4s. You must increase the size of the bottleneck, like add multiple RAID 0 spindles for your HDD spindle. You simply can't have 9 women deliver a baby in a single month...
Remus Rusanu
How did you infer that I don't understand :) Anyway, IO is a reasonable assumption, which wasn't taken into account before, now it looks like it describes the reason.
Tim
In fact, IO was the reason: after increasing server's memory and CPU we've got the desired result.
Tim

related questions