הבלוג של גרי רשף

19/09/2010

השפעת האינדקס על חיפוש בטבלה

Filed under: Uncategorized — תגיות: , , , , , , — גרי רשף @ 18:48

ניצור טבלה- בשלב ראשון ללא אינדקס:

Use tempdb;

Go


If object_id('SalesOrderDetail') Is Not Null Drop Table SalesOrderDetail;

Go


Create Table SalesOrderDetail(SalesOrderID int,

                            SalesOrderDetailID int,

                            CarrierTrackingNumber nvarchar(25) NULL,

                            OrderQty smallint,

                            ProductID int,

                            SpecialOfferID int,

                            UnitPrice money,

                            UnitPriceDiscount money,

                            LineTotal money,

                            rowguid Varchar(Max) ,

                            ModifiedDate datetime)

Go


Insert Into SalesOrderDetail

Select *

From AdventureWorks.Sales.SalesOrderDetail;

Go

נעיין ב-Execution Plan של חיפוש פשוט בטבלה:

Select *

From SalesOrderDetail

Where SalesOrderDetailID=100000;

clip_image002

המערכת סורקת את הטבלה כדי למצוא את השורות המתאימות: בהיעדר אינדקס- יש לבצע חיפוש מלא.

כעת ניצור אינדקס פשוט על העמודה המפולטרת:

Create Index Idx_1 On SalesOrderDetail(SalesOrderDetailID);

Go

clip_image004

כעת התבצע Seek על האינדקס והשורה הרלוונטית נמצאה מייד, אך מכיוון שהמערכת מעוניינת להציג את כל השורה (Select *) ולא רק את ערכה של העמודה עליה התבצע החיפוש- יש לחזור על ידי Lookup לטבלה, למצוא את החסר, ולהתאים לערך האינדקס (Nested Loops).

אם נבצע חיפוש אחר טווח גדול מספיק של שורות-

Select *

From SalesOrderDetail

Where SalesOrderDetailID Between 1000 And 1600;

clip_image006

כשהטווח מספיק גדול (אצלי- מעל 540) – המערכת מעדיפה לבצע Scan על הטבלה ולוותר על האינדקס, מכיוון שהמחיר של ה-Lookup המתבצע על כל שורה – גדול מדי.

מה יקרה אם ניצור Index Clustered במקום הקודם?

Drop Index SalesOrderDetail.Idx_1;

Go


Create Clustered Index Idx_2 On SalesOrderDetail(SalesOrderDetailID);

Go

clip_image008

פעולת ה-Seek על האינדקס מספיקה כעת מכיוון שה-Clustered Index הוא הטבלה וכשמצאנו את הערך המבוקש – כל השורה בידינו.

מה יקרה אם במקום Clustered Index ניצור אינדקס רגיל על העמודה המפולטרת אבל נכלול בו את כל העמודות (Covered Index)?

Drop Index SalesOrderDetail.Idx_2;

Go


Create Index Idx_3 On SalesOrderDetail(SalesOrderDetailID) Include

(SalesOrderID,CarrierTrackingNumber,OrderQty,ProductID,SpecialOfferID,UnitPrice,UnitPriceDiscount,LineTotal,rowguid,ModifiedDate);

Go

clip_image010

הפעם התבצע Index Seek ללא Look Up מכיוון שהאינדקס כלל את הכל.

מבחינת היעילות – Clustered Index ו-Covered Index – לשניהם הביצועים הכי טובים, אם כי ה-Covered Index בזבזני מבחינת משאבים ונתוני הטבלה נשמרים פעמיים.

מודעות פרסומת

להגיב »

עדיין אין תגובות.

RSS feed for comments on this post. TrackBack URI

להשאיר תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

יצירה של אתר חינמי או בלוג ב־WordPress.com.

%d בלוגרים אהבו את זה: