我从web api在sql server 2008 R2中插入数据。大约有300条记录插入到3到4个表中。在几毫秒之后,可以轻松插入前20到30条记录,之后插入记录需要几秒到几分钟。 sql server安装在Windows Server 2012 R2中。
如果在插入后删除相同的记录,然后再次调用api插入相同的数据,则插入只需2到3秒。
这是api代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ProductsApp.ApplicationLogics;
using System.Web.Http.Cors;
using Newtonsoft.Json;
namespace ProductsApp.Controllers
{
[EnableCors(origins: "*", headers: "*", methods: "POST")]
public class DataPostController : ApiController
{
[AcceptVerbs("POST")]
public string DataPost([FromBody] List<Models.ReadingData> model)
{
if (model == null)
{
return "Data not found!";
}
string sql, id1;
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["APIConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlTransaction tran = con.BeginTransaction())
{
foreach (var item in model)
{
sql = @"INSERT INTO TableA(Col1, Col2, Col3, Col4)
SELECT @Col1, @Col2, @Col3, @Col4;
SELECT SCOPE_IDENTITY();";
using (SqlCommand sqlCommand = new SqlCommand(sql, con, tran))
{
sqlCommand.Parameters.AddWithValue("@Col1", item.value1);
sqlCommand.Parameters.AddWithValue("@Col2", item.value2);
sqlCommand.Parameters.AddWithValue("@Col3", item.value3);
try
{
id1 = Convert.ToString(sqlCommand.ExecuteScalar());
if (item.amount > 0)
{
if (item.something != "0")
{
sql = @"INSERT INTO TableB(Col1, Col2, Col3)
SELECT @Col1, @Col2, @Col3;";
using (SqlCommand sqlCommand2 = new SqlCommand(sql, con, tran))
{
sqlCommand2.Parameters.AddWithValue("@Col1", id1);
sqlCommand2.Parameters.AddWithValue("@Col2", item.value5);
sqlCommand2.Parameters.AddWithValue("@FiscalYearId", item.value6);
try
{
sqlCommand2.ExecuteNonQuery();
}
catch (SqlException ex)
{
tran.Rollback();
return ex.Message;
}
}
}
}
if (item.advanceAmount > 0 || item.outstandingAmount > 0)
{
sql = @"UPDATE CustomersInfo SET AdvanceAmount=0, OutstandingAmount=0 WHERE CustomerId=@CustomerId;
UPDATE COAR SET IsClear=1 WHERE CustomerId=@CustomerId;
INSERT INTO COAR(FiscalYearId, CustomerId, EntryByUserId, OutstandingAmount, AdvanceAmount)
SELECT @FiscalYearId, @CustomerId, @EntryByUserId, @OutstandingAmount, @AdvanceAmount;";
}
else
{
sql = @"UPDATE CustomersInfo SET AdvanceAmount=0 WHERE CustomerId=@CustomerId;
UPDATE COAR SET IsClear=1 WHERE CustomerId=@CustomerId;";
}
using (SqlCommand sqlCommand2 = new SqlCommand(sql, con, tran))
{
sqlCommand2.Parameters.AddWithValue("@FiscalYearId", item.FiscalYearId);
sqlCommand2.Parameters.AddWithValue("@CustomerId", item.CustomerId);
sqlCommand2.Parameters.AddWithValue("@EntryByUserId", item.MeterReaderId);
sqlCommand2.Parameters.AddWithValue("@OutstandingAmount", item.outstandingAmount);
sqlCommand2.Parameters.AddWithValue("@AdvanceAmount", item.advanceAmount);
try
{
sqlCommand2.ExecuteNonQuery();
}
catch (SqlException ex)
{
tran.Rollback();
return ex.Message;
}
}
/*Insert Spot Fine (if any)*/
if (item.Fine > 0)
{
sql = @"INSERT INTO CreditSales(CreditSalesDateAD, CreditSalesDateBS, FiscalYearId,
CustomerId, ParticularsId, Amount, EntryByUserId, Status, MonthSN, MonthId)
SELECT @CreditSalesDateAD, @CreditSalesDateBS, @FiscalYearId,
@CustomerId, @ParticularsId, @Amount, @EntryByUserId, @Status, @MonthSN, @MonthId;";
using (SqlCommand sqlCommand4 = new SqlCommand(sql, con, tran))
{
sqlCommand4.Parameters.AddWithValue("CreditSalesDateAD", item.meterReadingDateAD);
sqlCommand4.Parameters.AddWithValue("CreditSalesDateBS", item.meterReadingDateBS);
sqlCommand4.Parameters.AddWithValue("FiscalYearId", item.FiscalYearId);
sqlCommand4.Parameters.AddWithValue("CustomerId", item.CustomerId);
sqlCommand4.Parameters.AddWithValue("ParticularsId", 5); //Always will be 5
sqlCommand4.Parameters.AddWithValue("Amount", item.Fine);
sqlCommand4.Parameters.AddWithValue("EntryByUserId", item.MeterReaderId);
sqlCommand4.Parameters.AddWithValue("Status", "0");
sqlCommand4.Parameters.AddWithValue("MonthSN", item.monthSN);
sqlCommand4.Parameters.AddWithValue("MonthId", item.MonthId);
try
{
sqlCommand4.ExecuteNonQuery();
}
catch (SqlException ex)
{
tran.Rollback();
return ex.Message;
}
}
}
/*If any tap repair complain*/
if (item.TapRepair == 1)
{
sql = @"INSERT INTO TapRepairs(ComplainDateAD, ComplainDateBS, FiscalYearId, CustomerId, ComplainTypeId,
RepairDateAD, RepairDateBS, RepairDescription, RepairByUserId)
SELECT @ComplainDateAD, @ComplainDateBS, @FiscalYearId, @CustomerId, @ComplainTypeId,
@RepairDateAD, @RepairDateBS, @RepairDescription, @RepairByUserId;";
using (SqlCommand sqlCommand5 = new SqlCommand(sql, con, tran))
{
sqlCommand5.Parameters.AddWithValue("@ComplainDateAD", item.meterReadingDateAD);
sqlCommand5.Parameters.AddWithValue("@ComplainDateBS", item.meterReadingDateBS);
sqlCommand5.Parameters.AddWithValue("@FiscalYearId", item.FiscalYearId);
sqlCommand5.Parameters.AddWithValue("@CustomerId", item.CustomerId);
sqlCommand5.Parameters.AddWithValue("@ComplainTypeId", item.Remarks);
sqlCommand5.Parameters.AddWithValue("@RepairDateAD", item.meterReadingDateAD);
sqlCommand5.Parameters.AddWithValue("@RepairDateBS", "");
sqlCommand5.Parameters.AddWithValue("@RepairDescription", "");
sqlCommand5.Parameters.AddWithValue("@RepairByUserId", item.MeterReaderId);
try
{
sqlCommand5.ExecuteNonQuery();
}
catch (SqlException ex)
{
tran.Rollback();
return ex.Message;
}
}
}
}
catch (SqlException ex)
{
if (ex.Message.Contains("MeterReadingEntries_FYID_MID_CID"))
{
//If meter reading entry already done
continue;
}
else
{
tran.Rollback();
return ex.Message;
}
}
}
}
tran.Commit();
con.Close();
con.Dispose();
}
}
return "ok";
}
}
}
每个表仅包含最多10列。 可能是什么原因? api有什么问题吗?为什么在删除并重新插入相同记录后插入速度很快?
更新: Profiler图片 Profiler Attached Image
答案 0 :(得分:0)
除了创建存储过程并将批处理发送到存储过程之外,我肯定会补充一点,即每个循环中每个查询的执行计划可能不同。
这篇文章已经解决了这个问题: SQL Query slow in .NET application but instantaneous in SQL Server Management Studio
看看erikkallen写的答案