mil*_*dba 5 performance join sql-server optimization exists query-performance
下面的查询非常慢(运行超过一分钟),我已将问题缩小到OR
操作员 ( ...OR (EXISTS (SELECT...
)。
我使用实时执行来验证 OR 语句的表之间是否存在嵌套循环连接,然后将记录连接回EmailTable
执行计划中的 。
基本上,EmailTable
正在被探查两次。
如果我添加提示OPTION (MERGE JOIN)
,查询将在一秒钟内完成。
请告诉我如何重写此查询,以便优化器默认选择更好的计划。
EmailTable
并且TeamMembers
在 上有聚集索引INS_ID
。表上的统计数据经常更新。
DECLARE @a INT
,@b BIT
,@c INT
,@d INT
,@e INT;
SELECT [XYZ].[CNT] AS [C]
FROM (
SELECT COUNT(1) AS [CNT]
FROM [dbo].[EmailTable] AS [table1]
WHERE ([table1].[INS_ID] = @a)
AND ([table1].[ACTIVE] = 1)
AND ([table1].[QUEUED_TO_SEND] = @b)
AND ([table1].[OWNER_USER_ID] <> @c)
AND (
([table1].[OWNER_USER_ID] IN (- 1))
OR (N'Allusers' = [table1].[VISIBLE_TO])
OR ([table1].[OWNER_USER_ID] = @d)
OR (
EXISTS (
SELECT 1 AS [C]
FROM [dbo].[TeamMembers] AS [table2]
WHERE ([table1].[INS_ID] = [table2].[INS_ID])
AND ([table1].[VISIBLE_TEAM_ID] = [table2].[TEAM_ID])
AND ([table2].[INS_ID] = [table1].[INS_ID])
AND ([table2].[MEMBER_USER_ID] = @d)
AND ([table2].[TEAM_ID] = [table1].[VISIBLE_TEAM_ID])
)
)
)
) AS [XYZ];
Run Code Online (Sandbox Code Playgroud)
两个表之间存在一些冗余 JOIN,并且在嵌套查询中使用太多OR
条件有时会压垮 SQL 查询优化器。
清理和组织代码后,我提出了以下(希望是等效的)替代方案:
DECLARE @a INT
,@b BIT
,@c INT
,@d INT
,@e INT;
SELECT SUM(CNT) AS [C]
FROM (
SELECT COUNT(1) AS [CNT]
FROM [dbo].[EmailTable]
WHERE 1 = 1
AND [ACTIVE] = 1
AND [INS_ID] = @a
AND [QUEUED_TO_SEND] = @b
AND [OWNER_USER_ID] <> @c
AND (
[OWNER_USER_ID] IN (- 1)
OR N'Allusers' = [VISIBLE_TO]
OR [OWNER_USER_ID] = @d
)
UNION ALL
SELECT COUNT(1) AS [CNT]
FROM [dbo].[EmailTable] AS [table1]
WHERE 1 = 1
AND [table1].[ACTIVE] = 1
AND [table1].[INS_ID] = @a
AND [table1].[QUEUED_TO_SEND] = @b
AND [table1].[OWNER_USER_ID] <> @c
AND EXISTS (
SELECT 1 AS [C]
FROM [dbo].[TeamMembers] AS [table2]
WHERE [table2].[INS_ID] = [table1].[INS_ID]
AND [table2].[TEAM_ID] = [table1].[VISIBLE_TEAM_ID]
AND [table2].[MEMBER_USER_ID] = @d
)
) XYZ
OPTION(RECOMPILE);
Run Code Online (Sandbox Code Playgroud)
让我们知道它是如何工作的,并可能按照一些评论者的要求发布实际执行计划。
归档时间: |
|
查看次数: |
380 次 |
最近记录: |