这里有两个问题。
1)有没有人知道为什么在每秒合并2,000辆车时我的CPU使用率会很高?
2)好奇,有没有办法在没有高CPU使用率的情况下每秒合并10,000辆车?
//Table & Index syntax...
CREATE TABLE [dbo].[Dealer_SalesVehicles](
[RawID] [bigint] IDENTITY(1,1) NOT NULL,
[AccountID] [bigint] NOT NULL,
[StockNumber] [nvarchar](50) NOT NULL,
[Vin] [nvarchar](30) NOT NULL,
[Year] [nvarchar](50) NOT NULL,
[Make] [nvarchar](50) NOT NULL,
[Model] [nvarchar](50) NOT NULL,
[Style] [nvarchar](80) NOT NULL
CONSTRAINT [PK_Dealer_SalesVehicles_AccountId_StockNumber_Vin] PRIMARY KEY CLUSTERED
(
[AccountID] ASC,
[StockNumber] ASC,
[Vin] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY]
//Sql Query...
var sqlAsk = "";
var rowAffected = 0;
var errorSqlParameters = new List<Tuple<string, string>>(); ;
using (var dbConnection = new SqlConnection(this._databaseConnectionString))
{
using (var dbCommand = dbConnection.CreateCommand())
{
sqlAsk = "";
sqlAsk += " MERGE ";
sqlAsk += " TOP (1)[dbo].[Dealer_SalesVehicles] WITH(HOLDLOCK) AS t ";
sqlAsk += " USING ";
sqlAsk += " (SELECT ";
sqlAsk += " @parmAccountId, @parmStockNumber, @parmVin ";
sqlAsk += " ) ";
sqlAsk += " AS s ";
sqlAsk += " ( ";
sqlAsk += " [AccountID], [StockNumber], [VIN] ";
sqlAsk += " ) ";
sqlAsk += " ON(t.[AccountId] = s.[AccountId] AND t.[StockNumber] = s.[StockNumber] AND t.[Vin] = s.[Vin]) ";
//#-- if matched, update existing record if right conditions are met(see Description in header)...
sqlAsk += " WHEN MATCHED AND(t.[AccountId] = s.[AccountId]) AND t.[StockNumber] = s.[StockNumber] AND(t.[Vin] = s.[Vin]) THEN ";
sqlAsk += " UPDATE SET ";
//AccountID...
//StockNumber...
//VIN...
sqlAsk += " t.[Year] = @parmYear, ";
sqlAsk += " t.[Make] = @parmMake, ";
sqlAsk += " t.[Model] = @parmModel, ";
sqlAsk += " t.[Style] = @parmStyle ";
//#-- if not matched, add new record and set return values...
sqlAsk += " WHEN NOT MATCHED THEN ";
//#--http://stackoverflow.com/questions/1609208/need-help-with-the-merge-statement...
//#--(Cannot use "s." or "t." here, for source or target table - name - abbreviation cuz "Columns name in the insert list can only refer to the target table, so the parser doesn't expect to see a table alias there, wouldn't know how to resolve it. It sees "column1", it knows it belongs to the target table. It sees "table1.column1", it doesn't know what "table1" means. "table1" is out of scope, so to speak")...
sqlAsk += " INSERT( ";
//RawID...
sqlAsk += " [AccountID], [StockNumber], [VIN], ";
sqlAsk += " [Year], [Make], [Model], [Style] ";
sqlAsk += " ) ";
sqlAsk += " VALUES( ";
sqlAsk += " @parmAccountId, @parmStockNumber, @parmVin, ";
sqlAsk += " @parmYear, @parmMake, @parmModel, @parmStyle ";
sqlAsk += " ) ";
sqlAsk += " ; "; //#--required semicolon separator for MERGE....
dbCommand.CommandTimeout = 60;
dbCommand.CommandText = sqlAsk;
dbCommand.Parameters.Clear();
dbCommand.Parameters.Add(new SqlParameter("@parmAccountId", SqlDbType.BigInt)).Value = parmSqlSalesVehicleRequest.DealerBranchAccountId;
dbCommand.Parameters.Add(new SqlParameter("@parmStockNumber", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.StockNumber;
dbCommand.Parameters.Add(new SqlParameter("@parmVin", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.Vin;
dbCommand.Parameters.Add(new SqlParameter("@parmYear", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.Year;
dbCommand.Parameters.Add(new SqlParameter("@parmMake", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.Make;
dbCommand.Parameters.Add(new SqlParameter("@parmModel", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.Model;
dbCommand.Parameters.Add(new SqlParameter("@parmStyle", SqlDbType.NVarChar)).Value = parmSqlSalesVehicleRequest.Style;
foreach (SqlParameter sqlParameter in dbCommand.Parameters)
{
errorSqlParameters.Add(new Tuple<string, string>(sqlParameter.ParameterName, sqlParameter.Value.ToString()));
}
if (dbConnection.State == ConnectionState.Open) { dbConnection.Close(); }
await dbConnection.OpenAsync();
rowAffected = await dbCommand.ExecuteNonQueryAsync();
}
}
答案 0 :(得分:0)
创建一个存储过程:
CREATE PROCEDURE dbo.usp_Add
(
@parmAccountId ...,
@parmStockNumber
)
AS BEGIN
SET NOCOUNT ON;
MERGE TOP(1) dbo.Dealer_SalesVehicles WITH (HOLDLOCK) t
USING (
SELECT [AccountID] = @parmAccountId,
[StockNumber] = @parmStockNumber,
[VIN] = @parmVin
) s ON t.[AccountId] = s.[AccountId]
AND t.[StockNumber] = s.[StockNumber]
AND t.[Vin] = s.[Vin]
WHEN MATCHED
THEN UPDATE
SET
t.[year] = @parmYear,
t.[Make] = @parmMake,
t.[model] = @parmModel,
t.[style] = @parmStyle
WHEN NOT MATCHED
THEN INSERT ([AccountID], [StockNumber], [VIN], [year], [Make], [model], [style])
VALUES (@parmAccountId, @parmStockNumber, @parmVin, @parmYear, @parmMake, @parmModel, @parmStyle);
END
GO
从您的代码中执行此SP。