假设我们要将值的数组作为参数传递给SP,在SP中将其用作IN子句中的值。

在性能方面哪个更好:

1-将值作为逗号分隔的字符串传递



Select * FROM myTable WHERE Id IN (@myConcatenatedValues)


要么

2-将值作为表变量传递包括一列,该列将这些值保存为行



Select * FROM myTable WHERE Id IN (Select Id from @myVariableTable)


提前致谢

最佳答案

我使用以下3个查询对此进行了快速测试:

DECLARE @UsersInString VARCHAR(255) = '1, 2, 3, 4, 5, 6, 7, 8, 9, 10'

/* Prone to SQL Injection, do not use like this! Sanitise your inputs */
EXEC (' SELECT * FROM [dbo].[User] WHERE UserID IN ( ' + @UsersInString + ' ) ')
GO


和:

DECLARE @UsersInTable TABLE (
    UserID INT
)

INSERT INTO @UsersInTable
VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

SELECT *
FROM [dbo].[User] U
JOIN @UsersInTable UT ON UT.UserID = U.UserID


和:

DECLARE @UsersInTable TABLE (
    UserID INT
)

INSERT INTO @UsersInTable
VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

SELECT *
FROM [dbo].[User] U
WHERE U.UserID IN (
    SELECT UserID
    FROM @UsersInTable
)


返回的实际执行计划表明,在我的情况下,顶层查询更快。该查询仅使用Clustered Index Seek

中间查询与Clustered Index Seek一起稍微慢一些,它还在表变量上使用了Table Scan

底部查询与Clustered Index SeekTable Scan一起运行甚至更慢,它还在表变量上执行了Sort。可以假设尝试针对排序后的聚簇索引优化IN ()查询。

但是,它很大程度上取决于要查询的列的索引。以及构建字符串或表变量所需的时间。

一个相当重要的旁注:将值作为逗号分隔的字符串传递可能会很冒险;您将必须使用字符串连接来动态构造IN ()语句;这可能会让您对SQL注入持开放态度。

关于sql - 如果使用IN子句,则用逗号分隔值或表变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18228096/

10-09 03:39