只有当记录不存在时,才通过存储过程从TVP列表中插入项目—性能缓慢
本文关键字:列表 TVP 插入项目 缓慢 性能 存储过程 记录 不存在 | 更新日期: 2023-09-27 18:28:07
我需要从.NET 4.5应用程序调用一个存储过程。作为ORM,我使用Dapper。
只有当具有car_id
的汽车不存在时,存储过程才接受TVP参数并将汽车从列表插入表Cars
。
表格:
CREATE TABLE USERS
(
CAR_ID int IDENTITY PRIMARY KEY,
CAR_NAME varchar(255),
)
TVP:
CREATE TYPE dbo.CarType
AS TABLE
(
CAR_ID int null,
CAR_NAME varchar(800) not null,
);
存储过程:
CREATE PROCEDURE dbo.InsertCars
@Cars AS CarType READONLY
AS
BEGIN
DECLARE @CountOfNew int
INSERT INTO CARS (CAR_ID, CAR_NAME)
SELECT C.CAR_ID, C.CAR_NAME
FROM @CARS C
WHERE NOT EXISTS(SELECT 1 FROM CARS WHERE CAR_ID = C.CAR_ID)
SET @CountOfNew = @@ROWCOUNT
RETURN @CountOfNew
END
问题是存储过程的性能。如果表中存在超过30000辆汽车,则存储过程调用需要20秒。
我调试我的应用程序,通过SQL Server Management Studio进行测试,在我看来,瓶颈是存储过程。
关于如何调整此存储过程的任何建议。
我使用SQL Server 2012。
感谢
运行SQL Server Profiler并包含Showplan Statistics XML Profile事件。对大型案例(>=30000辆汽车)运行查询,看看它的作用。
根据您的SQL Server版本,您可能会尝试MERGE(如果在SQL 2008或更高版本上)或LEFT JOIN WHERE Car_ID IS NULL,如下所示:
INSERT INTO CARS (CAR_ID, CARNAME)
SELECT C.CAR_ID, C.CARNAME
FROM @CARS C
LEFT JOIN Cars ON Cars.CAR_ID = C.CAR_ID
WHERE Cars.Car_ID IS NULL -- the car does not already exist
此外,您可以尝试将CarType声明为具有CAR_ID的PRIMARY KEY。
(我假设TVP CarType键是CAR_ID,而不是您所写的CARID。此外,您将此表声明为USERS而不是CARS。)