Have a query that takes over a minute to run
Table has over 2 million rows
[sID] is the PK
[textHash] is indexed and allows nulls
Both indexes have less than 1% fragmentation
What I want to to is add [textHash] match to the the basic where
Since [textHash] can be null need the two join conditions
Because of the way other conditions are built up Union on the main select is not an option.
In the next major release changing up the way queries are built to be able to use UNION.
In general I want to join on a property that can be null
If it is null then include the row based on PK
Select top 10001 [docFam].[sID]
From [docSVsys] with (nolock)
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock)
On [docSVsys].[sID] = [docFam].[sID]
Or [docSVsys].[textHash] = [docFam].[textHash]
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc
If some would please tell my how to copy the query plan I will include it
I tried HASH, MERGE, and LOOP hints.
The first two the compiler rejected and the LOOP was slower then no hint.
I tried
On ([docSVsys].[textHash] is null and [docSVsys].[sID] = [docFam].[sID])
Or [docSVsys].[textHash] = [docFam].[textHash]
And it was slower
A similar query runs in 2 seconds
But in this case [sParID] is not null so I only need the one join condition
Select top 10001 [docFam].[sID]
From [docSVsys] with (nolock)
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock)
On [docSVsys].[sParID] = [docFam].[sParID]
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc
For queries that return a small number of rows APPLY works.
This syntax below runs in 1 second versus 1 minute for the syntax above (returns 1,022 rows).
Still have a problem with both forms of the query for conditions that return a lot of rows but I don't view that as a SQL or syntax problem - a lot of rows is going to take longer.
Select [docFam].[sID]
From [docSVsys] with (nolock)
OUTER APPLY -- cross apply
(
Select [docSVsysHashNull].[sID]
From [docSVsys] as [docSVsysHashNull]with (nolock)
where [docSVsysHashNull].[sID] = [docSVsys].[sID]
union
Select [docSVsysHashNotNull].[sID]
From [docSVsys] as [docSVsysHashNotNull]with (nolock)
where [docSVsysHashNotNull].[sID] != [docSVsys].[sID]
and [docSVsysHashNotNull].[textHash] = [docSVsys].[textHash]
) as docFam
Where [docSVsys].[sID] <= '1000'
Group By [docFam].[sID]
Order By [docFam].[sID] Asc