只有当记录不存在时,才通过存储过程从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。

感谢

只有当记录不存在时,才通过存储过程从TVP列表中插入项目—性能缓慢

运行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。)