The query below is very slow (running over a minute) and I have narrowed down the issue to the OR
operator (...OR (EXISTS (SELECT...
).
I used live execution to verify that there is a nested loop join between the tables for the OR statement and then records are joined back to the EmailTable
in the execution plan.
Basically, EmailTable
is being probed twice.
If I add a hint OPTION (MERGE JOIN)
, the query is finishing within a second.
Please show me how to re-write this query so that the optimizer chooses a better plan by default.
EmailTable
and TeamMembers
has clustered index on INS_ID
. Statistics on the tables are updated often.
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];