SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


Prepared vs dynamic SQL odd execution plan


Prepared vs dynamic SQL odd execution plan

Author
Message
Vanyel01
Vanyel01
Forum Newbie
Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: General Forum Members
Points: 9 Visits: 28
I have a SQL statement that is resulting in widely differing execution plans depending on the format of the SQL submitted. The end result of both queries is exactly the same, however one results in an index seek and the other an index scan. I'd like to understand why this is happening and if there's a way to force the plan to use an index seek instead. That said, the straight SQL is:

UPDATE
BILL_INSTALLMENT
SET
BILL_INSTALLMENT.A_BITM_COMM = 0.00 ,
BILL_INSTALLMENT.D_BITM_COMM_AC = NULL ,
BILL_INSTALLMENT.C_BITM_COMM_AC = NULL ,
BILL_INSTALLMENT.A_BITM_COMM_AC = NULL ,
BILL_INSTALLMENT.A_INST_MIN_DUE = 44.64 ,
BILL_INSTALLMENT.D_INST_MIN_DUE_AC = NULL ,
BILL_INSTALLMENT.C_INST_MIN_DUE_AC = NULL ,
BILL_INSTALLMENT.A_INST_MIN_DUE_AC = NULL ,
BILL_INSTALLMENT.A_INST_TOT_PD = 44.64 ,
BILL_INSTALLMENT.D_INST_TOT_PD_AC = NULL ,
BILL_INSTALLMENT.C_INST_TOT_PD_AC = NULL ,
BILL_INSTALLMENT.A_INST_TOT_PD_AC = NULL ,
BILL_INSTALLMENT.C_BITM_TYP = N'KYS' ,
BILL_INSTALLMENT.C_INST_PAY_PRY = N'40' ,
BILL_INSTALLMENT.C_INST_NTC_TYP = 1 ,
BILL_INSTALLMENT.C_INST_TRN = N'RN' ,
BILL_INSTALLMENT.D_INST_DUE = '2007-03-21 00:00:00.000' ,
BILL_INSTALLMENT.N_CLT_ID_UID = 10088 ,
BILL_INSTALLMENT.D_INST = '2007-03-21 00:00:00.000' ,
BILL_INSTALLMENT.D_INST_DUE_ORIG = '2007-03-21 00:00:00.000' ,
BILL_INSTALLMENT.D_INST_SENT_TO_GL = '2007-02-22 00:00:00.000'
WHERE
BILL_INSTALLMENT.N_INST_OID = 1001

Whereas, when I use prepared statement format, I end up executing the following SQL (I'm not including the DECLARE and variable assignment statements to try and shorten this, but they are set correctly):

UPDATE
BILL_INSTALLMENT
SET
BILL_INSTALLMENT.A_BITM_COMM = @P3 ,
BILL_INSTALLMENT.D_BITM_COMM_AC = @P4 ,
BILL_INSTALLMENT.C_BITM_COMM_AC = @P5 ,
BILL_INSTALLMENT.A_BITM_COMM_AC = @P6 ,
BILL_INSTALLMENT.A_INST_MIN_DUE = @P7 ,
BILL_INSTALLMENT.D_INST_MIN_DUE_AC = @P8 ,
BILL_INSTALLMENT.C_INST_MIN_DUE_AC = @P9 ,
BILL_INSTALLMENT.A_INST_MIN_DUE_AC = @P10 ,
BILL_INSTALLMENT.A_INST_TOT_PD = @P11 ,
BILL_INSTALLMENT.D_INST_TOT_PD_AC = @P12 ,
BILL_INSTALLMENT.C_INST_TOT_PD_AC = @P13 ,
BILL_INSTALLMENT.A_INST_TOT_PD_AC = @P14 ,
BILL_INSTALLMENT.C_BITM_TYP = @P15 ,
BILL_INSTALLMENT.C_INST_PAY_PRY = @P16 ,
BILL_INSTALLMENT.C_INST_NTC_TYP = @P17 ,
BILL_INSTALLMENT.C_INST_TRN = @P18 ,
BILL_INSTALLMENT.D_INST_DUE = @P19 ,
BILL_INSTALLMENT.N_CLT_ID_UID = @P25 ,
BILL_INSTALLMENT.D_INST = @P26 ,
BILL_INSTALLMENT.D_INST_DUE_ORIG = @P27 ,
BILL_INSTALLMENT.D_INST_SENT_TO_GL = @P28
WHERE
BILL_INSTALLMENT.N_INST_OID = @P29


When I use the straight-forward SQL my execution plan includes an index seek on the PK field N_INST_OID. When I use the prepared statement format my execution plan includes an index scan on the PK field N_INST_OID. BTW, in case it is relevant, the primary key (@P29) is defined as a decimal(38,0).



John Rowan
John Rowan
SSChampion
SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)

Group: General Forum Members
Points: 12998 Visits: 4588
In your first example, the optimizer can use the value you've passed in (1001) and actually look at the distribution of the index to determine if an index seek could be used. When you run the same query and pass it a parameter instead of an explicit value, the Query Optimizer must look at all of the values in the query and create an execution plan based off of the selectivity of all of the index values. In this case, the Optimizer determines that an index scan would be more efficient. I would guess that your value of 1001 is fairly selective with regards to the other values in the index.

Does that help?

John Rowan

======================================================
======================================================
Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
Vanyel01
Vanyel01
Forum Newbie
Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: General Forum Members
Points: 9 Visits: 28
John Rowan (6/11/2008)
In your first example, the optimizer can use the value you've passed in (1001) and actually look at the distribution of the index to determine if an index seek could be used. When you run the same query and pass it a parameter instead of an explicit value, the Query Optimizer must look at all of the values in the query and create an execution plan based off of the selectivity of all of the index values. In this case, the Optimizer determines that an index scan would be more efficient. I would guess that your value of 1001 is fairly selective with regards to the other values in the index.

Does that help?


Thanks for your response...

Yes, the value of 1001 is the primary key, so the selectivity should be one-to-one. That is part of what confuses me. Regardless of the value of @P29, if it is matching on the PK, why would there be any question on selectivity? Is there a hint, or some other method of getting the optimizer to use a seek?



Wildcat
Wildcat
Ten Centuries
Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)Ten Centuries (1.2K reputation)

Group: General Forum Members
Points: 1183 Visits: 1444
Check this article:
http://sqlinthewild.co.za/index.php/2008/02/25/parameter-sniffing-pt-2/

---- I got this from Gail Shaw.Smile
Vanyel01
Vanyel01
Forum Newbie
Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: General Forum Members
Points: 9 Visits: 28
That was exactly what I was looking for! Thank you much!!



Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search