SQL查询速度

时间:2011-12-01 09:16:54

标签: sql performance reporting

我正在构建一个整理大量数据的报告,报告的数据已形成为一个在大约2到9秒内运行的视图(这是可以接受的)。我还有一个函数返回一组需要过滤视图的id:

select *
from vw_report
where employee_id in (select id from dbo.fnc_security(@personRanAsID))

安全功能本身在不到一秒的时间内运行。但是当我将上述两者结合起来时,查询需要15分钟。

视图和安全功能都做了相当多的工作,所以最初我认为它可能是锁定,我没有尝试锁定安全功能,但它没有任何区别。

关于我可能出错的地方的任何提示或技巧?

值得注意的是,当我将函数的结果复制到声明的部分内容时:

select *
from vw_report
where employee_id in (123, 456, 789)

速度增加回到2到9秒。

3 个答案:

答案 0 :(得分:2)

首先,任何额外的背景都会有帮助...
- 你有视图和功能的代码吗?
- 您是否可以指定用于引用的表的模式和索引?

如果没有这些,建议变得困难,但我会有刺...

1)。您可以将IN子句更改为Join 2)。您可以在视图上指定WITH(NOEXPAND)。

SELECT
  *
FROM
  vw_report WITH (NOEXPAND)
INNER JOIN
  (select id from dbo.fnc_security(@personRanAsID)) AS security
    ON security.id = vw_report.employee_id

注意:我先尝试没有NOEXPAND。

另一种选择是,索引的组合和视图的制定使得优化者很难创建一个好的执行计划。根据我上面提到的额外信息,这个可能可以改进。

答案 1 :(得分:0)

由于从vw_report为每一行执行子选择查询而第二个查询没有执行,因此需要花费很多时间。你应该使用类似的东西:

select *
from vw_report r, (select id from dbo.fnc_security(@personRanAsID)) v
where r.employee_id = v.id

答案 2 :(得分:0)

我最终将安全功能的结果转储到临时表中,并在主查询中使用临时表。事实证明这是最快的方法。

e.g:

create table #tempTable (id bigint)

select id 
into #tempTable
from dbo.fnc_security(@personRanAsID)

select *
from vw_report
where id in (select id from #tempTable)