הצגת "דפים" מתוך טבלה – מחידושי Denali

22/11/2010

אין תגובות

בימי SQL Server 2000 העליזים, כשהיינו צריכים להציג את שורות מספר 21-30 (למשל) מתוך הטבלה (בדרך כלל עבור אתרי אינטרנט בהם מציגים מסך של תוצאות וניתן לעבור למסך הקודם או הבא על ידי Prev ו-Next בהתאמה)- היינו שולפים את 30 השורות הראשונות, ממיינים הפוך ושולפים את 10 הראשונות (ליתר דיוק- 10 האחרונות מתוך ה-30), וזו השליפה המבוקשת:

Select  Top 10 name

From    (Select Top 30 name

        From    sys.objects

        Order   By name) T

Order By name Desc;

Go

  

עשיתי לעצמי כאן הנחה קטנה: את התוצאה של השליפה הזו צריך למיין חזרה לפי name, ולשם כך יש להפוך את מה שכתבתי לשאילתת משנה שניתן להוסיף לה מיון.. בגרסת 2005 התווספה אופציית מספור השורות, וכעת ניתן היה לשלוף את שורות 21-30 בקלות רבה יותר ועם קוד מובן יותר:

Select  name

From    (Select Row_Number() Over (Order By name) Mispar,

                name

        From    sys.objects) T

Where   Mispar Between 21 And 30;

בהחלט שיפור בבהירות, ובנוסף- משתי רמות של קינון (בהנחה שנוסיף לשליפה הראשונה מיון עולה כנדרש)- ירדנו לרמת קינון אחת. גרסת Denali – SQL 2011 – מביאה את בשורת ה-Offset:

Select  name

From    sys.objects

Order By name

Offset 20 Rows Fetch Next 10 Rows Only;

כעת אין צורך בקינון כלל, ומדובר בפתרון יעודי לבעייה ספציפית (תרגום: נדלג על 20 ונשלוף את 10 הבאות). ומה המחיר הקמעונאי ללקוח: clip_image002 ניתן לראות שיפור הדרגתי של כ-10% בביצועים (במקרה זה!), ולמרות שזו אינה מהפכה – זה בגדר Nice to have. כדאי לשים לב שבשליפות הראשונה והאחרונה המערכת העדיפה לבצע Scan לאינדקס ולא לטבלה (Clustered Index) ולשלם ב-Key LookUp שכן מדובר בשליפה של חלק מהשורות, ואילו בשליפה השניה- יש צורך למספר את כל השורות ולכן מתבצע Clustered Index Scan על כל הטבלה. מה שלא הצלחתי להבין זה מדוע יש צורך ב-LookUp אם התבצע Scan על אינדקס של עמודת name (אם הוא לא על name- מדוע נבחר האינדקס הזה?).

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

כתיבת תגובה

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

הצגת "דפים" מתוך טבלה – מחידושי Denali

אין תגובות

בימי SQL Server 2000 העליזים, כשהיינו צריכים להציג את שורות מספר 21-30 (למשל) מתוך הטבלה (בדרך כלל עבור אתרי אינטרנט בהם מציגים מסך של תוצאות וניתן לעבור למסך הקודם או הבא על ידי Prev ו-Next בהתאמה)- היינו שולפים את 30 השורות הראשונות, ממיינים הפוך ושולפים את 10 הראשונות (ליתר דיוק- 10 האחרונות מתוך ה-30), וזו השליפה המבוקשת:

Select Top 10 name
From (Select Top 30 name
From sys.objects
Order By name) T
Order By name Desc;
Go

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

בגרסת 2005 התווספה אופציית מספור השורות, וכעת ניתן היה לשלוף את שורות 21-30 בקלות רבה יותר ועם קוד מובן יותר:

Select  name
From (Select Row_Number() Over (Order By name) Mispar,
name
From sys.objects) T
Where Mispar Between 21 And 30;

בהחלט שיפור בבהירות, ובנוסף- משתי רמות של קינון (בהנחה שנוסיף לשליפה הראשונה מיון עולה כנדרש)- ירדנו לרמת קינון אחת.

גרסת Denali – SQL 2011 – מביאה את בשורת ה-Offset:

Select  name
From sys.objects
Order By name
Offset 20 Rows Fetch Next 10 Rows Only;

כעת אין צורך בקינון כלל, ומדובר בפתרון יעודי לבעייה ספציפית (תרגום: נדלג על 20 ונשלוף את 10 הבאות).

ומה המחיר הקמעונאי ללקוח:

clip_image002

ניתן לראות שיפור הדרגתי של כ-10% בביצועים (במקרה זה!), ולמרות שזו אינה מהפכה – זה בגדר Nice to have.

כדאי לשים לב שבשליפות הראשונה והאחרונה המערכת העדיפה לבצע Scan לאינדקס ולא לטבלה (Clustered Index) ולשלם ב-Key LookUp שכן מדובר בשליפה של חלק מהשורות, ואילו בשליפה השניה- יש צורך למספר את כל השורות ולכן מתבצע Clustered Index Scan על כל הטבלה. מה שלא הצלחתי להבין זה מדוע יש צורך ב-LookUp אם התבצע Scan על אינדקס של עמודת name (אם הוא לא על name- מדוע נבחר האינדקס הזה?).

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

כתיבת תגובה

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