Thank you Arunraj for pointing me to that post.
Considering that list of Causes of Connection Termination, I decided to modify the CTE based algorithm to achieve higher speed and script
completion.
About the higher execution speed: after a quick search, I found this really interesting post by Jeff Moden (
http://www.sqlservercentral.com/articles/T-SQL/74118/ ), about performances of different counting implementations based on CTEs.
The best performing one, with zero reads and the lowest CPU usage is the CROSS JOINED Cascaded CTE that uses less inner steps than the
method I was previously using.
The script of my initial post became:
declare @numUsers int = 500000;
WITH
E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
),
-- 1*10^1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), -- 1*10^2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), -- 1*10^4 or 10,000 rows
E8(N) AS (SELECT 1 FROM E4 a, E4 b), -- 1*10^8 or 100,000,000 rows
cteTally(N) AS (SELECT TOP (@numUsers) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E8)
insert SocialUsers(idUser, UserName)
SELECT N, 'FullName'+ convert(varchar(12), N ) AS username
FROM cteTally
The old version run in
1':15", while this one runs in just 15". A huge improvement.
My worst case was the
100,000,000 rows version that took 3h :53':57" to complete in the old version (I was able to complete it just 1 time on 6 trials).
The new version for 100,000,000 rows now took
1h:19':44", again a big improvement but, most important, it was able to complete the execution without the connection dropping.
About the connection drops: they were linked with the log file usage exceeding the 1 GB limit.
I was already loading the rows in 200 "batches" of 500,000 rows, but this was apparently not enough to avoid log related issues.
I tried with 400 batches of 250,000 rows but was still getting a 40552 error msg.
Being the sql azure recovery model = full and having a limited set of ALTER DATABASE options, I opted for the faster solution: drop and
recreate the db. Starting with an empty log and running my 100M rows in 400 batches gave the correct result.
Overall it has been an interesting lesson. I will now move on the next step of my perf tests.
Cheers,
Mario