我正在尝试像这样优化查询:
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()?
答案 0 :(得分:1)
试试这个 -
变体#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
)
变体#2:
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
变体#3:
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)