Hi,
I have this query that (stripped right down) goes something like this :
SELECT
[Person_PrimaryContact].[LegalName],
[Person_Manager].[LegalName],
[Person_Owner].[LegalName],
[Person_ProspectOwner].[LegalName],
[Person_ProspectBDM].[LegalName],
[Person_ProspectFE].[LegalName],
[Person_Signatory].[LegalName]
FROM [Cache]
LEFT JOIN [dbo].[Person] AS [Person_Owner] WITH (NOLOCK)
ON [Person_Owner].[PersonID] = [Cache].[ClientOwnerID]
LEFT JOIN [dbo].[Person] AS [Person_Manager] WITH (NOLOCK)
ON [Person_Manager].[PersonID] = [Cache].[ClientManagerID]
LEFT JOIN [dbo].[Person] AS [Person_Signatory] WITH (NOLOCK)
ON [Person_Signatory].[PersonID] = [Cache].[ClientSignatoryID]
LEFT JOIN [dbo].[Person] AS [Person_PrimaryContact] WITH (NOLOCK)
ON [Person_PrimaryContact].[PersonID] = [Cache].[PrimaryContactID]
LEFT JOIN [dbo].[Person] AS [Person_ProspectOwner] WITH (NOLOCK)
ON [Person_ProspectOwner].[PersonID] = [Cache].[ProspectOwnerID]
LEFT JOIN [dbo].[Person] AS [Person_ProspectBDM] WITH (NOLOCK)
ON [Person_ProspectBDM].[PersonID] = [Cache].[ProspectBDMID]
LEFT JOIN [dbo].[Person] AS [Person_ProspectFE] WITH (NOLOCK)
ON [Person_ProspectFE].[PersonID] = [Cache].[ProspectFEID]
Person is a huge table and each join to it has a pretty significant hit in the execution plan.
Is there anyway I can adjust this query so that I am only linking to it once, or at least get SQL Server to scan through it only once?
EDIT
Here is the plan:
|--Parallelism(Gather Streams)
|--Merge Join(Right Outer Join, MERGE:([Person_ProspectFE].[PersonID])=([Cache].[ProspectFEID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_ProspectFE].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ProspectFEID] as [Cache].[ProspectFEID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_ProspectFE].[PersonID]), ORDER BY:([Person_ProspectFE].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_ProspectFE]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ProspectFEID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ProspectFEID]))
|--Merge Join(Right Outer Join, MERGE:([Person_ProspectBDM].[PersonID])=([Cache].[ProspectBDMID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_ProspectBDM].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ProspectBDMID] as [Cache].[ProspectBDMID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_ProspectBDM].[PersonID]), ORDER BY:([Person_ProspectBDM].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_ProspectBDM]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ProspectBDMID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ProspectBDMID]))
|--Merge Join(Right Outer Join, MERGE:([Person_ProspectOwner].[PersonID])=([Cache].[ProspectOwnerID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_ProspectOwner].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ProspectOwnerID] as [Cache].[ProspectOwnerID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_ProspectOwner].[PersonID]), ORDER BY:([Person_ProspectOwner].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_ProspectOwner]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ProspectOwnerID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ProspectOwnerID]))
|--Merge Join(Right Outer Join, MERGE:([Person_PrimaryContact].[PersonID])=([Cache].[PrimaryContactID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_PrimaryContact].[PersonID]=[PracticeManagement].[dbo].[ListCache].[PrimaryContactID] as [Cache].[PrimaryContactID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_PrimaryContact].[PersonID]), ORDER BY:([Person_PrimaryContact].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_PrimaryContact]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[PrimaryContactID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[PrimaryContactID]))
|--Merge Join(Right Outer Join, MERGE:([Person_Signatory].[PersonID])=([Cache].[ClientSignatoryID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_Signatory].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ClientSignatoryID] as [Cache].[ClientSignatoryID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_Signatory].[PersonID]), ORDER BY:([Person_Signatory].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_Signatory]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ClientSignatoryID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ClientSignatoryID]))
|--Merge Join(Right Outer Join, MERGE:([Person_Manager].[PersonID])=([Cache].[ClientManagerID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_Manager].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ClientManagerID] as [Cache].[ClientManagerID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_Manager].[PersonID]), ORDER BY:([Person_Manager].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_Manager]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ClientManagerID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ClientManagerID]))
|--Merge Join(Right Outer Join, MERGE:([Person_Owner].[PersonID])=([Cache].[ClientOwnerID]), RESIDUAL:([PracticeManagement].[dbo].[Person].[PersonID] as [Person_Owner].[PersonID]=[PracticeManagement].[dbo].[ListCache].[ClientOwnerID] as [Cache].[ClientOwnerID]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Person_Owner].[PersonID]), ORDER BY:([Person_Owner].[PersonID] ASC))
| |--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[Person].[Person_PK] AS [Person_Owner]), ORDERED FORWARD)
|--Sort(ORDER BY:([Cache].[ClientOwnerID] ASC))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([Cache].[ClientOwnerID]))
|--Clustered Index Scan(OBJECT:([PracticeManagement].[dbo].[ListCache].[IX_ListCache_Type] AS [Cache]))