Sql server 如何避免WHERE子句中的函数USER_ID()

Sql server 如何避免WHERE子句中的函数USER_ID(),sql-server,where,clause,Sql Server,Where,Clause,我正在尝试优化查询,如下所示: SELECT id, type, parent_id FROM [dbo].[v5] with(nolock) WHERE ( USER_ID() = 1 OR ( v5.type IN (1,2,3) and EXISTS ( SELECT obj_id FROM dbo.access

我正在尝试优化查询,如下所示:

SELECT  id, type, parent_id
FROM    [dbo].[v5] with(nolock)
WHERE 
(
    USER_ID() = 1
    OR
        (
            v5.type IN (1,2,3)
            and 
            EXISTS
            (
                    SELECT obj_id FROM dbo.access with(nolock) 
                    where  access.obj_id = id 
                    AND obj_id.[u_name] in 
                    (
                        select SUSER_SNAME() union all 
                        select [name] COLLATE database_default from dbo.u_role
                    )
            )
        )
)
它工作25秒。当我评论这句话时:

--USER_ID() = 1
 --     OR
它工作5秒。如何优化此查询?如何避免在where子句中使用USER_ID()-

变体#1:

DECLARE @user INT
SELECT @user = USER_ID() --<--

SELECT 
      v.id
    , v.[type]
    , v.parent_id
FROM dbo.v5 v WITH (NOLOCK)
LEFT JOIN (
    SELECT DISTINCT a.obj_id 
    FROM dbo.access a WITH(NOLOCK) 
    WHERE a.[u_name] IN 
        (
            SELECT SUSER_SNAME() 
            UNION ALL 
            SELECT [name] COLLATE database_default 
            FROM dbo.u_role
        )
) a ON a.obj_id = v.id 
WHERE @user = 1
    OR (
            v5.[type] IN (1, 2, 3) 
        AND 
            a.obj_id IS NOT NULL
    )
IF USER_ID() = 1 BEGIN

    SELECT 
          v.id
        , v.[type]
        , v.parent_id
    FROM dbo.v5 v WITH (NOLOCK)

END
ELSE BEGIN

    SELECT 
          v.id
        , v.[type]
        , v.parent_id
    FROM dbo.v5 v WITH (NOLOCK)
    JOIN (
        SELECT DISTINCT a.obj_id 
        FROM dbo.access a WITH(NOLOCK) 
        WHERE a.[u_name] IN 
            (
                SELECT SUSER_SNAME() 
                UNION ALL 
                SELECT [name] COLLATE database_default 
                FROM dbo.u_role
            )
    ) a ON a.obj_id = v.id 
    WHERE v5.[type] IN (1, 2, 3) 

END
DECLARE @user INT
SELECT @user = USER_ID()

SELECT  id, [type], parent_id
FROM [dbo].[v5] WITH(NOLOCK)
WHERE @user = 1
    OR (
        v5.[type] IN (1,2,3)
        AND 
        EXISTS (
            SELECT 1 
            FROM dbo.access WITH(NOLOCK) 
            WHERE access.obj_id = id 
                AND access.[u_name] IN 
                    (
                        SELECT SUSER_SNAME() 
                        UNION ALL 
                        SELECT [name] COLLATE database_default 
                        FROM dbo.u_role
                    )
        )
    )
OPTION (RECOMPILE)
变体#3:

DECLARE @user INT
SELECT @user = USER_ID() --<--

SELECT 
      v.id
    , v.[type]
    , v.parent_id
FROM dbo.v5 v WITH (NOLOCK)
LEFT JOIN (
    SELECT DISTINCT a.obj_id 
    FROM dbo.access a WITH(NOLOCK) 
    WHERE a.[u_name] IN 
        (
            SELECT SUSER_SNAME() 
            UNION ALL 
            SELECT [name] COLLATE database_default 
            FROM dbo.u_role
        )
) a ON a.obj_id = v.id 
WHERE @user = 1
    OR (
            v5.[type] IN (1, 2, 3) 
        AND 
            a.obj_id IS NOT NULL
    )
IF USER_ID() = 1 BEGIN

    SELECT 
          v.id
        , v.[type]
        , v.parent_id
    FROM dbo.v5 v WITH (NOLOCK)

END
ELSE BEGIN

    SELECT 
          v.id
        , v.[type]
        , v.parent_id
    FROM dbo.v5 v WITH (NOLOCK)
    JOIN (
        SELECT DISTINCT a.obj_id 
        FROM dbo.access a WITH(NOLOCK) 
        WHERE a.[u_name] IN 
            (
                SELECT SUSER_SNAME() 
                UNION ALL 
                SELECT [name] COLLATE database_default 
                FROM dbo.u_role
            )
    ) a ON a.obj_id = v.id 
    WHERE v5.[type] IN (1, 2, 3) 

END
DECLARE @user INT
SELECT @user = USER_ID()

SELECT  id, [type], parent_id
FROM [dbo].[v5] WITH(NOLOCK)
WHERE @user = 1
    OR (
        v5.[type] IN (1,2,3)
        AND 
        EXISTS (
            SELECT 1 
            FROM dbo.access WITH(NOLOCK) 
            WHERE access.obj_id = id 
                AND access.[u_name] IN 
                    (
                        SELECT SUSER_SNAME() 
                        UNION ALL 
                        SELECT [name] COLLATE database_default 
                        FROM dbo.u_role
                    )
        )
    )
OPTION (RECOMPILE)

它不应该需要5秒钟的时间。请添加表和索引。Thanx将重试。在视图中使用此查询如何?