Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.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_Sql Server 2008 - Fatal编程技术网

Sql server 如何提高此查询的性能?

Sql server 如何提高此查询的性能?,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有一个SQL查询,它在MSSQL 2008 R2上运行 ViewvMobileLastMobileHistory大约有1000行和 从vMobileLastMobileHistory中选择*需要0.2秒 但是这个查询需要5秒钟,我如何优化这个代码? (我认为问题是相交,但我不知道如何改变这一点) 问题是,如果您的iSytemUser列上有任何索引,Optimize将无法使用它们,因为它必须考虑传递的特定用户ID或返回的所有结果,最好在逻辑上将这两种情况分开。此外,由于您不关心辅助表中的任何列,

我有一个SQL查询,它在MSSQL 2008 R2上运行 View
vMobileLastMobileHistory
大约有1000行和
从vMobileLastMobileHistory中选择*需要0.2秒

但是这个查询需要5秒钟,我如何优化这个代码? (我认为问题是相交,但我不知道如何改变这一点)


问题是,如果您的
iSytemUser
列上有任何索引,Optimize将无法使用它们,因为它必须考虑传递的特定用户ID或返回的所有结果,最好在逻辑上将这两种情况分开。此外,由于您不关心辅助表中的任何列,因此对于特定用户,可以使用
EXISTS
,以利用半联接:

IF (@UserID = -1)
BEGIN
    SELECT  DISTINCT *
    FROM    vMobileLastMobileHistory;
END
ELSE
BEGIN
    SELECT  DISTINCT *
    FROM    vMobileLastMobileHistory AS mh
    WHERE   EXISTS 
            (   SELECT  1 
                FROM    Contractor_User AS cu 
                WHERE   cu.strContractor = mh.strContractor 
                AND     cu.iSystemUser = @UserID
            )
    AND     EXISTS 
            (   SELECT  1 
                FROM    Region_User AS ru 
                WHERE   ru.strRegion = mh.strRegion 
                AND     ru.iSystemUser = @UserID
            )
    AND     EXISTS 
            (   SELECT  1 
                FROM    MobileType_DomainAction AS da 
                        INNER JOIN MobileType_User AS mu
                            ON mu.MobileID = da.ID
                WHERE   da.tiMobileType = mh.tiMobileType 
                AND     mu.iSystemUser = @UserID
            );

END 
现在,对于每种情况,您可以有两个执行计划(返回所有结果,或针对特定用户),在每种情况下,您只需要从
vMobileLastMobileHistory
读取一次,并且还可以通过删除
INTERSECT
并替换为3
EXISTS
子句来限制所需的排序

如果它们还不存在,那么您也可以考虑表上的一些索引。找出哪些索引有帮助的一个好方法是在SQLServerManagementStudio中运行查询,并启用“显示实际执行计划”选项,这将显示任何缺少的索引。

。您没有共享数据,因此根据我的知识和此链接,我将intersect查询替换为Internal join查询,如下所示:

--我认为您不需要明确的上限查询。如果您有问题,请通知我

        SELECT DISTINCT vml.* 
        FROM   vMobileLastMobileHistory vml
            LEFT OUTER JOIN MobileType_DomainAction mtda ON mtda.tiMobileType = vml.tiMobileType
            LEFT OUTER JOIN MobileType_User ON MobileType_User.MobileID = mtda.ID
            LEFT OUTER JOIN dbo.Region_User ON dbo.vml.strRegion = dbo.Region_User.strRegion
            LEFT OUTER JOIN Contractor_User ON vml.strContractor = Contractor_User.strContractor
        WHERE 
        (MobileType_User.UserID = @UserID 
        and Region_User.iSystemUser = @UserID or Contractor_User.iSystemUser = @UserID
        ) OR @UserID = - 1        

使用简单的
加入
,可能会对您有更好的帮助。:)谢谢平局时间缩短为1秒。这是GreatThanks Ajay,但此查询正在运行,但需要花费太长时间。为了减少时间,只需在连接条件中附加where条件。
        SELECT DISTINCT vml.* 
        FROM   vMobileLastMobileHistory vml
            LEFT OUTER JOIN MobileType_DomainAction mtda ON mtda.tiMobileType = vml.tiMobileType
            LEFT OUTER JOIN MobileType_User ON MobileType_User.MobileID = mtda.ID
            LEFT OUTER JOIN dbo.Region_User ON dbo.vml.strRegion = dbo.Region_User.strRegion
            LEFT OUTER JOIN Contractor_User ON vml.strContractor = Contractor_User.strContractor
        WHERE 
        (MobileType_User.UserID = @UserID 
        and Region_User.iSystemUser = @UserID or Contractor_User.iSystemUser = @UserID
        ) OR @UserID = - 1