Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 表值函数性能_Sql Server_Tsql - Fatal编程技术网

Sql server 表值函数性能

Sql server 表值函数性能,sql-server,tsql,Sql Server,Tsql,我有一个SQL Server表值函数,如下所示 CREATE FUNCTION dbo.GetDeptName ( @DId INT ) RETURNS TABLE AS RETURN ( SELECT DeptID , DeptName , Location FROM dbo.department WHERE D

我有一个SQL Server表值函数,如下所示

CREATE FUNCTION dbo.GetDeptName ( @DId INT )
RETURNS TABLE
    AS
        RETURN
        ( SELECT    DeptID ,
                    DeptName ,
                    Location
          FROM      dbo.department
          WHERE     Deptno = @DId
        );
现在我想使用这个表值函数从
Employee
表中获取数据。以下三种情况下,哪种情况下的50k记录性能更好

场景1:

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 );
场景2:

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:

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

这三个查询均未优化:

在查询中使用函数不是一个好的做法,因为在这种情况下,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条消息:

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

在扫描、逻辑读取和物理读取中具有较少值的查询是性能更好的查询


再见,试试这个。这可能是加入函数的最佳方式

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

你自己去看看吧。如果您意识到您没有使用参数@DId anywhere?,那么您的函数就没有where子句了。场景2的查询在语义上并不相同,因此将其性能与其他查询进行比较是没有意义的。