连接表值参数-Sql Server T Sql
我有一个接受表值参数的存储过程。仅当该表有值时,我才希望与该表进行联接连接表值参数-Sql Server T Sql,sql,sql-server,tsql,join,Sql,Sql Server,Tsql,Join,我有一个接受表值参数的存储过程。仅当该表有值时,我才希望与该表进行联接 CREATE PROC dbo.TestProc (@name UNIQUEIDENTIFIER = null, @hasCityGuids bit, @cityGuids dbo.GUIDTableType READONLY) AS BEGIN SELECT x1 , x2 FROM Address A WHERE (@hasCityGuids = 0
CREATE PROC dbo.TestProc
(@name UNIQUEIDENTIFIER = null,
@hasCityGuids bit,
@cityGuids dbo.GUIDTableType READONLY)
AS
BEGIN
SELECT x1 , x2
FROM Address A
WHERE (@hasCityGuids = 0
OR A.CityGuid IN (SELECT Value FROM @cityGuids))
END
另一个选项是进行外部联接
SELECT
x1 , x2
FROM
Address A
LEFT OUTER JOIN
@cityGuids CG ON A.CityGuid = CG.Value
有比这两个更快的选择吗?我有一个复杂的查询,我不得不在多个地方使用这个过滤器,这会减慢查询速度。如果这是我过去遇到的问题,那么它会很慢,因为这里有OR,并且优化器没有运行和使用索引
WHERE (@hasCityGuids = 0 OR A.CityGuid IN (
Select Value from @cityGuids ))
相反,我们最终得到了一个实际的IF语句,比如
CREATE PROC dbo.TestProc( @name UNIQUEIDENTIFIER = null,
@hasCityGuids bit,
@cityGuids dbo.GUIDTableType READONLY)
AS
BEGIN
IF @hasCityGuids = 0 THEN
BEGIN
SELECT x1 , x2
FROM Address A
END
ELSE
SELECT x1 , x2
FROM Address A INNER join @cityGuids CG ON A.CityGuid = CG.Value
END
你可以尝试一种新方法
BEGIN
SELECT x1 , x2
FROM Address A
WHERE (@hasCityGuids = 0
OR EXISTS ( SELECT null FROM @cityGuids innerHolder where innerHolder.Value = A.CityGuid)
END
您可以尝试将TVP值放入#temp表中,并在其水合后在其上创建索引
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
CREATE TABLE #Holder
(ID INT )
/* simulate your insert */
INSERT INTO #HOLDER (ID)
select 1 union all select 2 union all select 3 union all select 4
/*
select value from FROM @cityGuids
*/
/* CREATE CLUSTERED INDEX IDX_TempHolder_ID ON #Holder (ID) */
CREATE INDEX IDX_TempHolder_ID ON #Holder (ID)
/* then try exists */
SELECT x1 , x2
FROM Address A
WHERE (@hasCityGuids = 0
OR EXISTS ( SELECT null FROM #Holder innerHolder where innerHolder.Value = A.CityGuid)
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
如果该表有值,您希望与该表进行联接是什么意思。与其先检查值,不如直接加入它。你会进行不必要的检查。通过检查值,您已经在访问该表。在这种情况下,您还可以继续使用表执行联接或子查询。也许你可以采取不同的方法。你打算做什么?您的目标或最终目标是什么?问题是我的查询不是这样简单的,它有大约10个select子查询作为列,我必须对大多数子查询应用此筛选器。我不确定我是否可以在这里使用IF语句。为什么不能?如果TVP有行,则执行一个复杂查询,否则执行另一个查询。然后优化器可以为执行的查询选择最佳计划。好的,谢谢您的尝试。我不想重复几乎相同的逻辑两次,只是在外部连接逻辑上有所不同。但我想这是SQL的发展方向。好吧,值得注意的是,我们之间的区别在于内部连接。然后它可以使用索引,这使它更快。我不知道外太空人是否也有同样的好处。它可能取决于您的数据库和键/索引。哦,如果您有一组这样的过滤器,您的另一个选择是创建动态sql。您确实需要注意这些事情的安全性,但是动态创建sql,然后使用exec_sql执行它可能会真正提高性能。不过,它也可能会把它储存起来,所以你只能试一下,看看效果如何。如果不了解更多关于数据库的信息,很难说这会很好