2013-10-14 148 views
0

我有一些连接表的查询,当我使用=运营商,而不是运营商in在where子句中像这样我得到一个显著的性能提升。SQL服务器

  • =运营商需要不到一秒钟的时间。
  • in运营商需要一分钟左右的时间。

where P.GID in (SELECT GID from [dbo].[fn_SomeFunction] (15268))

子查询返回1周的结果在大多数情况下,只是这种变化将改善大多数情况下反而会造成一些其他情况下的错误。

任何想法,为什么这种行为?

+0

提供的实际查询会有所帮助。 –

+0

这是一个表值函数吗?如果是这样,请尝试交叉应用它,而不是将它放在子查询中 –

+0

如果您使用** IN **的方式发布,那不是一个提高性能的SARGable运算符(通常** IN **不是),而** = **运算符则是。 – Question3CPO

回答

1

尝试类似的东西,它不是测试,并可能包含一些语法错误。 主要想法是在临时表变量中获得所需的id并在连接中使用它。 希望有所帮助。

DECLARE @gids TABLE( 
GID UNIQUEIDENTIFIER NOT NULL 
) 

INSERT INTO @gids (GID) 
    SELECT 
     GID 
    FROM [dbo].[fn_SomeFunction](15268) 

SELECT * FROM SomeTable st INNER JOIN st.GID = @gids.GID 
0

如果真正代表一个功能,那就是被杀死你的执行时间。您可以通过查看执行计划来验证这一点。 会发生什么情况是,在你的子查询中,函数必须一遍又一遍地计算。如果您可以删除该功能并替换查询,则应该注意到有所改进。

此外,如果函数返回类型与列的类型不匹配,则需要对每个返回项目执行隐式转换。更改函数返回类型(或列类型)以匹配也将有助于性能。

日期时间<> SMALLDATETIME例如,需要一个隐式转换。

+0

我用实际的查询替换了函数,但它仍然在运算符中花费一分钟,while =运算符花费的时间不到一秒 – mmohab

+0

有没有办法知道它是否被一次又一次地执行? – mmohab

+0

您可以在查询执行计划中看到该信息(Ctrl + M并执行,您将看到底部的选项卡)。一个图标会带来巨大的成本。如果该项目是嵌套循环或转换,它会一遍又一遍地运行 – orgtigger