Sometimes you have to construct some data to do the test data, like this:
IF object_id(N'T14') is not NULLBEGIN DROP TABLET14ENDGOCREATE TABLET14 (t14_idINT)GODECLARE @i INT = 1 while @i <= +BEGIN INSERT intoT14 (t14_id)SELECT @i SET @i = @i + 1ENDGO
Code-1
There is a problem here, every time you run an insert equivalent to commit a transaction, the amount of data is not a problem, if you want to insert 1 million, 2 million, 10 million or more of the data? Since the INSERT statement is implicitly commit, the performance of the insert can be significantly improved by adding an explicit transaction outside the loop. Another way to improve performance is to use a CTE to insert data into a table at a time. Now make a comparison of the performance of the two methods of inserting data. Guess which is faster before there is no result? Or is it the same?
First, add a transaction, insert 1 million records:
IF object_id(N'T14') is not NULLBEGIN DROP TABLET14ENDGOCREATE TABLET14 (t14_idINT)GODBCCFreesessioncacheDBCCdropcleanbuffersGOSETNOCOUNT on;BEGIN TRANDECLARE @i INT = 1 while @i <= 1000000BEGIN INSERT intoT14 (t14_id)SELECT @i SET @i = @i + 1ENDCOMMIT TRAN;SETNOCOUNTOFF;GO
Code-2
I test on the machine several times, averaging, about 22 seconds to complete the insertion of 1 million records, the speed is very fast. (How long does it take to complete without an explicit transaction?) Interested friends can try it)
Here is the use of the CTE:
IF object_id(N'T15') is not NULLBEGIN DROP TABLET15ENDGOCREATE TABLET15 (t15_idINT)GODBCCFreesessioncacheDBCCdropcleanbuffersGO withCTE1 as ( SELECTA.[object_id] fromMaster.sys.all_objects asA, master.sys.all_objects asb), CTE2 as (SELECTRow_number () Over(ORDER by [object_id]) asRow_no fromCTE1)INSERT intoT15 (t15_id)SELECTRow_no fromCTE2WHERERow_no<= 1000000GO
Code-3
Also test the average number of times, unexpectedly is about 5 seconds to complete, greatly surprised me unexpectedly! Now insert 10 million records to see what the results are. The former only need to change the code-3 in the 1000000 to 10000000, and then run. The latter, due to the insufficient number of records for CTE1, requires union all two times, the code is as follows:
IF object_id(N'T15') is not NULLBEGIN DROP TABLET15ENDGOCREATE TABLET15 (t15_idINT)GODBCCFreesessioncacheDBCCdropcleanbuffersGO withCTE1 as ( SELECTA.[object_id] fromMaster.sys.all_objects asA, master.sys.all_objects asbUNION AllSELECTA.[object_id] fromMaster.sys.all_objects asA, master.sys.all_objects asbUNION AllSELECTA.[object_id] fromMaster.sys.all_objects asA, master.sys.all_objects asb), CTE2 as (SELECTRow_number () Over(ORDER by [object_id]) asRow_no fromCTE1)INSERT intoT15 (t15_id)SELECTRow_no fromCTE2WHERERow_no<= 10000000GO
Code-4
test Result : The insertion of the transaction will take about 3 minutes, and the CTE will be completed no more than 1.5 of the time. It seems that the CTE is more efficient! During the test, the memory usage is not much, but the CPU usage is obviously improved. In addition, inserting large data into the table, with or without indexes and the log recovery model, can also affect the performance of the insert.
Comparison of disposable transactions and CTE insert data