2011-12-01 94 views
0

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

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秒。

+0

这很难回答,如果我们不知道你正在使用(Oracle,MySQL等,SQL服务器和PostgreSQL,SQLite的...)和什么RDBMS的版本是什么RDBMS。它们的SQL实现有所不同,有些功能可以用来提高查询效率。 – Benoit

回答

0

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

例如为:

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) 
0

由于从vw_report中为每一行执行子选择查询,而第二个查询不执行,所以需要很多时间。你应该使用类似:

select * 
from vw_report r, (select id from dbo.fnc_security(@personRanAsID)) v 
where r.employee_id = v.id 
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第一。

另一种选择是,索引和视图组合的组合使优化器很难创建一个良好的执行计划。随着我所要求的额外信息,这可能是可以改进的。

+0

注意:NOEXPAND部分是MS SQL Server。其他RDBMS可能有类似的选项。 – MatBailie