שליפת "דפים" מטבלה תוך שימוש באינדקס רגיל

16/02/2013

תגיות: , , ,
תגובה אחת

בגרסאות 2005 – 2008R2 שליפה של דפים, למשל כמקובל בדפי אינטרנט שמחזירים חלק מהתוצאות, הייתה יכולה להיעשות באמצעות Row_Number: ממספרים את השורות בסט, ובכל פעם מחזירים "מֵאִייָה" אחרת.
אם יש אינדקס על העמודה לפיה התוצאות ממויינות – אזי מה טוב, ניתן לעשות שימוש בו:

Use tempdb;

Go

 

If Object_ID('T_Messages','U') Is Not Null Drop Table T_Messages;

 

Select * Into T_Messages From sys.messages;

 

Create Index Idx_T_Messages On T_Messages(Message_ID, Language_ID);

 

Select * From T_Messages;

clip_image002

With T As

(Select Row_Number() Over(Order By Message_ID, Language_ID) N,

        *

From    T_Messages)

Select  *

From    T

Where   N Between 201 And 300;

clip_image004

clip_image006

כפי שניתן לראות – המערכת מבצעת Index Scan כדי למצוא באמצעותו את מאה השורות שבדף השלישי (300-201), דא עקא שזה כרוך בביצוע Lookup יקר מאוד לטבלה מכיוון שבאינדקס נמצאים רק הערכים של שתי העמודות ולא של השאר (בניגוד ל-Clustered Index או לשימוש ב-Include), והגרוע מכל- המערכת מבצעת את ה-Lookup על כל 300 השורות הראשונות בטרם תשלוף את המאייה השלישית..

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

With T As

(Select Row_Number() Over(Order By Message_ID, Language_ID) N,

        Message_ID,

        Language_ID

From    T_Messages)

Select  Tm.*

From    T

Inner Join T_Messages Tm

        On T.Message_ID=Tm.Message_ID

        And T.Language_ID=Tm.Language_ID

Where   T.N Between 201 And 300;

ואם נשווה את הביצועים:

clip_image008

ההבדל בהחלט משמעותי.

מסקנות:

1. עדיף Clustered Index במידת האפשר.

2. אם כבר Index רגיל – לכלול את העמודות האחרות ב-Include.

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

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

תגובה אחת

  1. שי17/02/2013 ב 02:48

    תודה על המאמרים המעניינים!

    לא הצלחתי להבין מדוע הplan השני עדיף, החלק הראשון נראה בדיוק כמו הראשון..

    תודה.

    הגב