表值函数性能

时间:2017-04-12 10:09:33

标签: sql-server tsql

我有一个SQL Server Table Valued函数,如下所示。

CREATE FUNCTION dbo.GetDeptName ( @DId INT )
RETURNS TABLE
    AS
        RETURN
        ( SELECT    DeptID ,
                    DeptName ,
                    Location
          FROM      dbo.department
          WHERE     Deptno = @DId
        );

现在我想使用此表值函数从Employee表中获取数据。从以下3个场景中,哪一个可以为50k记录提供更好的性能。

情景1:

SELECT  *
FROM    dbo.employee
WHERE   deptname IN ( SELECT    deptname
                      FROM      dbo.GetDeptName(50) );

情景2:

SELECT  *
FROM    dbo.employee e
        JOIN dbo.GetDeptName (50) fn ON e.deptname = fn.deptname; 

场景3:

SELECT  *
FROM    dbo.employee e
WHERE   EXISTS ( SELECT 1
                 FROM   dbo.GetDeptName (50) fn
                 WHERE  e.deptname = fn.deptname );

2 个答案:

答案 0 :(得分:1)

所有三个查询都没有优化:

在查询中使用函数不是一个好习惯,因为在这种情况下,SQL引擎会对employee表的所有记录执行该函数。

无论如何,要知道三个中最好的是什么,你可以运行这个命令:

SET STATISTICS IO ON

select * from dbo.employee where deptname in(select deptname from dbo.GetDeptName(50))

select * from dbo.employee e join dbo.GetDeptName(50) fn on e.deptname =fn.deptname

select * from dbo.employee e where exists(select 1 from dbo.GetDeptName(50) fn where e.deptname =fn.deptname)

然后检查消息面板(结果右侧)的输出。

您将收到以下3条消息:

  

表'员工'。扫描计数1,逻辑读取2,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

扫描,逻辑读取和物理读取中具有较少值编号的查询是性能更好的查询。

答案 1 :(得分:-1)

试试这个。它可能是加入这些功能的最佳方式。

SELECT  *
FROM   dbo.employee e
cross apply ( SELECT deptname FROM dbo.GetDeptName(e.deptid))
where e.deptid=50