Let’s head straight to the example:
Query 1:
Select *
Into #temp_v1
From View1
Select *
Into #temp_v2
From View2
select *
From #temp_v1 v1
where not exists (
Select * From #temp_v2 where key = v1.key
)
This is much faster than
Query 2:
select *
From View1 v1
where not exists (
Select * From View2 where key = v1.key
)
Now, obviously, I have simplified the example. View1 is a view of views and and more comparisons are needed that make it difficult to use a join.
My question is really not how I should rather write my SQL, but how come SQL Server can execute query 1 in 3 seconds, and query 2 in 10 minutes.
And more importantly is there a magic option that I can give the optimizer to create an execution plan like query 1.
If your view is complicated, then accessing the view will be the slowest part of the operation by far, and query 1 minimizes that.
Suppose each view has 1,000,000 rows. In query 1, you are only retrieving a row from a view 2,000,000 times, while in query 2 you will likely retrieve a row from a view 500,000,000,000 times or more. (In a best-case scenario, every
v1.keywill exist in view 2. But you still have to check roughly half the rows in view 2 each time to verify that).I don’t know about execution plans in SQL server, but writing your query something like this should also be more efficient:
By getting all the keys from view 2 ahead of time, you essentially have the same efficiency of your query 1, without the temporary table step.