SQL Server 查询性能问题:需要替换 NOT EXISTS

Posted

技术标签:

【中文标题】SQL Server 查询性能问题:需要替换 NOT EXISTS【英文标题】:SQL Server Query Performance Issue: Need Replacement of NOT EXISTS 【发布时间】:2015-09-04 05:26:29 【问题描述】:

有人可以优化以下通用 SQL 查询的性能:

select fn.column1 
from dbo.function1(input1) as fn
where (not exists (select 1 from table1 t1 
                   where fn.column1 = t1.column1) 
       and not exists (select 1 from table2 t2 
                       where fn.column1 = t2.column1))

对于上述查询,请考虑下面给出的近似行数。

    select fn.column1 from dbo.function1(input1) as fn -- 2秒内返回64000条记录。

    表1(Column1)记录--返回3000条记录--1秒

    表2(Column1)记录——返回2000条记录——1秒

因此,如果我运行每个 select 语句,它会在 1 或 2 秒内提取并显示记录。但是,如果我运行完整的查询,显示 64000 - (3000 + 2000) = 59000 条记录需要一分钟多的时间。

我尝试像这样使用EXCEPT

 select fn.column1 
 from dbo.function1(input1) 

 except 

 (select column1 from dbo.table1 union select column1 from dbo.table2)

没有什么能提高我的表现。同样,显示 59000 条记录需要一分钟。这与“不在”场景中的情况相同。

我还注意到,如果我们在上面的查询中使用 UNION,而不是 EXCEPT,它会在 2 秒内返回 59K 条记录。

更新:

函数(有点复杂)包含以下伪代码

select column1, column2,...column6 
from dbo.table1 
inner join dbo.table2 
inner join ....
inner join dbo.table6 
inner join dbo.innerfunction1 
where <Condition 1>

UNION ALL

select column1, column2,...column6 
from dbo.table1 
inner join dbo.table2 
inner join ...
inner join dbo.table4 
inner join dbo.innerfunction2 
where (condition 2)

假设两个内部函数有单表选择语句

我的问题是:如果我从函数中选择列,它会在 1 秒内显示 64K 记录。但是,如果执行整个查询,则需要一分钟以上。

[请注意:该查询需要在函数中使用]

谁能帮我改进一下?

如果您需要更多详细信息或说明,请告诉我。

问候, 维斯瓦诉。

【问题讨论】:

你能显示dbo.function1的代码吗?这可能是罪魁祸首。 感谢菲利克斯的更新。请参阅更新:部分 if the function troubles, how the result retrieved in 1 second if I run the select statement of the function and not the whole query does? 请尝试重新表述该句子,因为它完全不清楚。 更新了!请检查! 【参考方案1】:

如果没有可玩的数据,它有点难以优化。小提琴会很好。尽管如此,这是一种可行的方法。 创建一个临时表,对其进行索引,然后执行以下操作:

SELECT
  fn.column1
INTO
  #temp  
FROM
  dbo.function1(input1) AS fn

CREATE NONCLUSTERED INDEX [temp_index] ON #temp 
(
    column1 ASC
)

SELECT
  column1
FROM
  #temp AS t
EXCEPT
(
  SELECT
    column1
  FROM
    dbo.table1
  UNION
  SELECT
    column1
  FROM
    dbo.table2
)

我会对结果感兴趣。

【讨论】:

您好约翰,感谢您的更新。我需要在函数中使用查询。 嗨,约翰。这完美地工作。但我需要把它放在一个函数中:(。请有任何建议! 嗨@salaiviswa,很遗憾你不能在函数中使用临时表(#表)。您可以使用表变量,但不能在表变量上创建索引(如果您在 column1 中的值是唯一的,则主键除外)。您唯一的选择是将此代码封装在存储过程而不是函数中。 嗨,约翰.. 抱歉回复晚了。感谢更新。我同意你说的。

以上是关于SQL Server 查询性能问题:需要替换 NOT EXISTS的主要内容,如果未能解决你的问题,请参考以下文章

SQLserver 怎么把查出的字符串结果作为子查询条件

提高 SQL Server 查询性能

sql server查询性能where子句

大型sql server查询性能优化

用 Sql Server 中的列数据替换行

SQL Server 2008 - 连接导致性能下降