我有一些 SQL 查询 IN
条款。为了改进查询计划缓存,我决定使用表值参数。
这是样本 WHERE ID IN (SELECT ID FROM @P1)
.
@P1 是以下类型的变量:
CREATE TYPE [dbo].[Ids] AS TABLE(
[ID] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
但我注意到有些查询变慢了。
这是查询示例:
select * from SomeTable s where ((s.SomeForeignId in (select id from @p1)) or s.SomeForeignId is null)
在我的数据库上执行 2.1 秒。
和旧查询:
select * from SomeTable s where ((s.SomeForeignId in (1,2,3.....)) or s.SomeForeignId is null)
在 1.8 秒内执行。
我注意到查询计划的不同。第一个查询的计划由两部分组成(一个用于空检查,一个用于 in 子句),然后是串联。而第二个计划只是索引搜索。
有什么方法可以改进我的参数化查询以更快地执行?
附言这只是蒸馏查询的示例,我想知道此
in (select id from @p1)
是否有任何不正确之处部分。
最佳答案
几个建议:
SELECT *
- just list the columns you actually need .EXISTS
而不是 IN
(因为前者可以短路):SELECT cols FROM dbo.SomeTable AS s
WHERE EXISTS (SELECT 1 FROM @p1 WHERE ID = s.SomeForeignId)
OR SomeForeignId IS NULL;
UNION
),但您可以尝试编写自己的 UNION ALL
避免 OR
:SELECT cols FROM dbo.SomeTable AS s
WHERE EXISTS (SELECT 1 FROM @p1 WHERE ID = s.SomeForeignId)
UNION ALL
SELECT cols FROM dbo.SomeTable
WHERE SomeForeignId IS NULL;
令我困扰的是,您现有的任何一个变体都需要将近两秒钟。请确保
SomeTable.SomeForeignId
上有索引- 不仅仅是一个外键约束,而是一个实际的非聚集索引。您的问题中不清楚这是您寻求的索引。
关于sql - in 子句的表值参数比 in 子句简单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16035466/