简体   繁体   English

与ADO.Net的SQL事务

[英]SQL Transaction with ADO.Net

I am new to Database interection with C#, I am trying to writing 10000 records in database in a loop with the help of SqlCommand and SqlConnection objects with the help of SqlTransaction and committing after 5000. It is taking 10 seconds to processed. 我是不熟悉C#的数据库交互的对象,我试图借助SqlCommand和SqlConnection对象借助SqlTransaction在一个循环中在数据库中写入10000条记录,并在5000年后提交。处理需要10秒钟。

SqlConnection myConnection = new SqlConnection("..Connection String..");
myConnection.Open();
SqlCommand myCommand = new SqlCommand();
myCommand.CommandText = "exec StoredProcedureInsertOneRowInTable Param1, Param2........";
myCommand.Connection = myConnection;
SqlTransaction myTrans = myConnection.Begintransaction();
for(int i=0;i<10000;i++)
{
mycommand.ExecuteNonQuery(); 
if(i%5000==0) 
{
myTrans.commit();  
myTrans = myConnection.BeginTransaction();  
mycommand.Transaction = myTrans;
}
}

Above code is giving me only 1000 rows write/sec in database. 上面的代码仅在数据库中每秒写入1000行。

But when i tried to implement same logic in SQL and execute it on Database with SqlManagement Studio the it gave me 10000 write/sec. 但是,当我尝试在SQL中实现相同的逻辑并使用SqlManagement Studio在数据库上执行该逻辑时,它给了我10000次写入/秒。 When I compare the behaviour of above two approch then it showes me that while executing with ADO.Net there is large number of Logical reads. 当我比较以上两种方法的行为时,它表明,在使用ADO.Net执行时,会有大量的逻辑读取。

my questions are: 1. Why there is logical reads in ADO.Net execution? 我的问题是:1. 为什么在ADO.Net执行中存在逻辑读取? 2. Is tansaction have some hand shaking? 2.交响乐中有握手吗? 3. Why they are not available in case of management studio? 3.为什么在Management Studio中不可用? 4. If I want very fast insert transactions on DB then what will be the approach? 4.如果我想在数据库上非常快速地插入事务,那将是什么方法? .

Updated Information about Database objects 有关数据库对象的更新信息

Table: tbl_FastInsertTest No Primary Key, Only 5 fields first three are type of int (F1,F2,F3) and last 2(F4,F5) are type varchar(30) 表: tbl_FastInsertTest无主键,只有5个字段,前三个是int类型(F1,F2,F3),最后两个(F4,F5)类型是varchar(30)

storedprocedure: StoredProcedure的:

create proc stp_FastInsertTest 
{ 
@nF1 int,
 @nF2 int,
 @nF3 int,
 @sF4 varchar(30),
 @sF5 varchar(30) 
 }
 as  
 Begin
 set NoCOUNT on
       Insert into tbl_FastInsertTest
       {
         [F1],
         [F2],
         [F3],
         [F4],
         [F5]
       }
       Values
       {
         @nF1,
         @nF2,
         @nF3,
         @sF4,
         @sF5,
       } end
 --------------------------------------------------------------------------------------

SQL Block Executing on SSMS 在SSMS上执行SQL块

--When I am executing following code on SSMS then it is giving me more than 10000 writes per second but when i tried to execute same STP on ADO than it gave me 1000 to 1200 writes per second -当我在SSMS上执行以下代码时,它每秒可以给我10000次以上的写入,但是当我尝试在ADO上执行相同的STP时,它每秒可以给我1000至1200次写入

--while reading no locks -读无锁

begin trans 
declare @i int 
set @i=0

While(1<>0) 
begin  
 exec stp_FastInsertTest 1,2,3,'vikram','varma'  
 set @i=@i+1 

 if(@i=5000)   
  begin    
   commit trans   
   set @i=0
   begin trans
  end

 end

If you are running something like: 如果您正在运行类似:

exec StoredProcedureInsertOneRowInTable 'blah', ...
exec StoredProcedureInsertOneRowInTable 'bloop', ...
exec StoredProcedureInsertOneRowInTable 'more', ...

in SSMS, that is an entirely different scenario, where all of that is a single batch. 在SSMS中,这是完全不同的情况,所有这些都是单个批处理。 With ADO.NET you are paying a round-trip per ExecuteNonQuery - I'm actually impressed it managed 1000/s. 使用ADO.NET,您需要为每个ExecuteNonQuery支付往返费用-实际上,我印象深刻的是它的管理速度为1000 / s。

Re the logical reads, that could just be looking at the query-plan cache, but without knowing more about StoredProcedureInsertOneRowInTable it is impossible to comment on whether something query-specific is afoot. 重新进行逻辑读取, 可能只是查看查询计划缓存,但是如果不了解StoredProcedureInsertOneRowInTable那么就不可能对特定于查询的内容进行评论了。 But I suspect you have some different SET conditions between SSMS and ADO.NET that is forcing it to use a different plan - this is in particular a problem with things like persisted calculated indexed columns, and columns "promoted" out of a sql-xml field. 但是我怀疑您在SSMS和ADO.NET之间有一些不同的SET条件,这迫使它使用不同的计划-这尤其是诸如持久化计算索引列以及从sql-xml中“提升”列之类的问题领域。

Re making it faster - in this case it sounds like a table-valued parameters is exactly the thing, but you should also review the other options here 重新使其更快-在这种情况下,听起来好像是一个表值参数 ,但是您还应该在这里查看其他选项

  • For performant inserts take a look at SqlBulkCopy class if it works for you it should be fast. 对于高性能插入,请查看SqlBulkCopy类(如果它对您有用),它应该很快。
  • As Sean said, using parameterized queries is always a good idea. 正如Sean所说,使用参数化查询始终是一个好主意。
  • Using a StringBuilder class, batching thousand INSERT statements in a single query and committing the transaction is a proven way of inserting data: 使用StringBuilder类,在单个查询中批处理数千条INSERT语句并提交事务是一种行之有效的数据插入方式:

    var sb=new StringBuilder(); var sb = new StringBuilder();

     for(int i=0;i < 1000;i++) { sb.AppendFormat("INSERT INTO Table(col1,col2) 

    VALUES({0},{1});",values1[i],values2[i]); } VALUES({0},{1});“,values1 [i],values2 [i]);}

     sqlCommand.Text=sb.ToString(); 
  • Your code doesn't look right to me, you are not committing transactions at each batch. 您的代码在我看来不正确,您不是在每个批次中都提交事务。 Your code keeps opening new transactions. 您的代码不断打开新交易。

  • It is always a good practice to drop indexes while inserting a lot of data, and adding them later. 在插入大量数据时删除索引并在以后添加它们始终是一个好习惯。 Indexes will slow down your writes. 索引会减慢您的写入速度。
  • Sql Management Studio does not have transactions but Sql has, try this: Sql Management Studio没有事务,但是Sql有,请尝试以下操作:
  BEGIN TRANSACTION MyTransaction INSERT INTO Table(Col1,Col1) VALUES(Val10,Val20); INSERT INTO Table(Col1,Col1) VALUES(Val11,Val21); INSERT INTO Table(Col1,Col1) VALUES(Val12,Val23); COMMIT TRANSACTION 

You need to use a parameterized query so that the execution path can get processed and cached. 您需要使用参数化查询,以便可以处理和缓存执行路径。 Since you're using string concatenation (shudder, this is bad, google sql injection) to build the query, SQL Server treats those 10,000 queries are separate, individual queries and builds an execution plan for each one. 由于您使用字符串串联(不方便,谷歌sql注入)来构建查询,因此SQL Server会将这10,000个查询视为独立的单个查询,并为每个查询建立执行计划。

MSDN: http://msdn.microsoft.com/en-us/library/yy6y35y8.aspx although you're going to want to simplify their code a bit and you'll have to reset the parameters on the command. MSDN: http : //msdn.microsoft.com/zh-cn/library/yy6y35y8.aspx,尽管您要稍微简化一下他们的代码,并且必须重置命令上的参数。

If you really, really want to get the data in the db fast, think about using bcp... but you better make sure the data is clean first (as there's no real error checking/handling on it. 如果您确实希望将数据快速放入db中,请考虑使用bcp ...,但最好先确保数据是干净的(因为没有真正的错误检查/处理方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM