en-UShe-IL
You are here:   Blog
Register   |  Login

Blog Archive:

Maximize
* Can be used in order to search for older blogs Entries

Search in blogs


Blog Categories:

Maximize
* Can be used in order to search for blogs Entries by Categories

Blog Tags:

Maximize
* Can be used in order to search for blogs by keywords

TNWikiSummit


Awared MVP 


 


Microsoft® Community Contributor 


Microsoft® Community Contributor


 Read first, before you you use the blog! Maximize
דצמ30

Written by: ronen ariely
30/12/2012 11:48 RssIcon

השאלה העומדת על הפרק היא כזו:

יש לנו שאילתה פשוטה של SELECT עם סינון לפי טור מסויים. נניח ID = 10000. כמו כן אנחנו רוצים לקחת את נתון זה כחלק מהנתונים החוזרים.

מה יהיה נכון יותר, לרשום את הערך בצורה מפורשת בחלק של ה SELECT או להישתמש בשם של הטור?

-- Using parameter VS using a fixed data
select id from QQ01 where id  = 10000
select 10000 from QQ01 where id  = 10000

הגיון פשוט יכול להוביל אותנו לצפות שהשאילתה השנייה תהיה מיטבית יותר. אחרי הכל במקרה השני אנחנו לא צריכים נתון ממסד הנתונים אלא עושים שימוש בערך קבוע. לכן יש מי שישאל לא איזה שאילתה טובה יותר אלא בכמה השאילתה השנייה משפרת את הביצוע. למעשה נראה שאין זו השאלה הנכונה. האם בכלל השאילתה השניה יעילה יותר?

השאילתה בכל מקרה צריכה לבדוק את הנתון בטור של is_active בגלל התנאי ב WHERE. ניתן בקלות להראות מצבים בהם תוכנית ההרצה תהיה שונה מפני שנוספת פעולה של Compute Scalar כדי להציג את המספר הקבוע, כך שהתשובה היא שדווקה שימוש במספר קבוע עלול אולי ליצור מעט יותר עומס כשמדובר בפעולה נוספת.

USE QQ
GO
 
-- ---------------------------------- DDL + DML
create table QQ01 (
id int identity(2,2)
,txt nvarchar(50)
)
GO
 
SET NOCOUNT ON
GO
 
select GETDATE();
GO
insert QQ01 (txt)
values (CONVERT(NVARCHAR(50), NEWID()))
GO 100000
select GETDATE();
GO
 
-- ---------------------------------- Query
select id, txt from QQ01
where id  = 10000
GO
select 10000 as id, txt from QQ01
where id  = 10000
GO
-- Check the execution plans
 
-- ---------------------------------- Clean
SET NOCOUNT OFF
GO
 
DROP table QQ01
GO

הנה תוכניות ההרצה שקיבלנו:

אבל שימו לב מה קורה בשנוי קטן של השאילתה :-) כאשר אני מגדיר את המספר מראש פעם אחת:

declare @S int = 10000
select @S as id, txt from QQ01
where id  = @S
GO

רמז :-)
החלטתי לא לצרף את תוכנית ההרצה מפני שאנחנו פשוט חוזרים לתוכנית ההרצה המקורית. המקרה הנוכחי אם לנו את החלק של Compute Scalar.

הסבר:

במקרה של שימוש במספר מנוע המיטוב ראה בכך חישוב על טור במסד הנתונים ולכן ביצע Compute Scalar. אם נכנסים למאפיינים ניתן לראות שמדובר על חישוב שבוצע בפועל כביכול עבור כל רשומה. זה מה שנקבל בתיאור:
Compute new values from existing values in a row
לעומת זאת כאשר ביצענו שימוש בפרמטר הרי שהוא לא חושב אלא הנתון נלקח מהפרמטר.

עם כל זה מומלץ ומאוד חשוב לעבור על ה XML עצמו ולראות נתונים נוספים שיש שם מעבר לתמונה שיכולים אולי לעזור במסקנה. ולזכור תמיד שזה רק מקרה מסויים שאנחנו מציגים וכל מקרה יש לחשוב לגופו של עניין.