Domanda

I have this query(of course with couple joins across tables and some views which I will call x for simplicity).

  1. Case 1 : select * from x -> returns in 10 sec, still acceptable, fairly heavy on joins and lot of data
  2. Case 2 : select * from x where userid = 1 -> returns in 0-1 sec, good enough
  3. Case 3 : using SP : if @userid = -1 select * from x else select from x where userid = @userid -> now calling sp with paramenter userid 1 should return on 0-1 sec as it should be comparable to case 2 but in fact it returns in 10 sec.

    Now, parameter masking OR WITH RECOMPILE on sp OR OPTION (recompile) on query with where clause doesn't help, What makes the SP run faster with userid = something is putting OPTION(recompile) on the first part of the SP ie on the query without where clause. :

  4. Case 4 : using SP : if @userid = -1 select * from x option (recompile) else select * from x where userid = @userid

Any explanation?

I can guess earlier it was using optimization based of query without where clause even for the query with where clause, but why is that?

È stato utile?

Soluzione

Stored procedures cache execution plans, so they don't have the overhead of recompiling a query every time the SP is called. This is particularly important when using stored procedures for transactions. It is much less important whent the queries are running for several seconds.

When a query takes parameters the stored procedure must decide what values to optimize for. I am guessing that your SQL Server recognizes the two queries as being identical, and is using the same cached plan for them. It is optimizing the plan based on the first query. This is speculation, but it would explain what you are seeing.

You can readily fix this with the following version of the query:

select *
from x
where @userid = -1 or userid = @userid
option (recompile)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top