שליפה אקראית של שורות מטבלה

11/02/2012

אין תגובות

מה נעשה אם נרצה להגביל מראש את מספר השורות הנשלפות כדי לא להעמיס על המערכת שלא לצורך,
או אם נרצה לשלוף בסדר אקראי כדי לא לראות בכל פעם אותן 20-30 שורות ראשונות,
או נבקש לבצע פעולה מורכבת יחסית על מדגם מייצג מהטבלה?
הרי בדרך כלל כשאנחנו צריכים להציץ בטבלה כדי להתרשם מ"מה יש שם", אנו כמקובל מפעילים פקודת Select, ממתינים בין שבריר שנייה למספר שניות שהריצה תסתיים, מעיינים, וממשיכים הלאה. אם מתברר שבטבלה יש כמה מליוני שורות והשליפה עלולה להימשך זמן רב- לוחצים כמקובל על האייקון האדום שעוצר את זה באמצע ומסתפקים במה שכבר נשלף.
מישהו נוהג אחרת? כנראה שלא..
אילו אופציות יותר מקצועיות עומדות לרשותנו למקרה הצורך?
האפשרות הראשונה היא למיין באופן אקראי בעזרת NewID:

Use AdventureWorks;

Go

 

Select Top 20 *

From   Sales.Customer

Order By NewID();

clip_image002

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

למערכת יש פתרון נוסף, פחות מוכר, ועם יותר פונקציונליות:

Select  *

From    Sales.Customer TableSample(20 Rows);

clip_image004

המערכת מבצעת במקרה זה Scan על הטבלה, ובוחרת אקראית 20 שורות מבלי למיין; וליתר דיוק- היא כנראה בוחרת נקודות אקראיות ושולפת רצף של שורות החל מכל אחת (או משהו בסגנון); כל זה בכפוף לחלק היחסי של 20 מכלל השורות. אני מציין זאת כי לרוב לא יחזרו 20 שורות בדיוק אלא בממוצע: לעיתים יותר, לעיתים פחות, ולעיתים בכלל לא.

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

Select  *

From    Sales.Customer TableSample(2 Percent);

clip_image006

במקרה זה חוזרות לי תמיד כפולות שלמות של 188 שורות (מתוך 19185), כאשר כל כפולה היא רציפה (שימו לב שבצילום המסך ה-CustomerID רציפים), ו-188 הוא ככל הנראה מספר השורות ב-Page (בנ"ל 103 Pages), וזה נותן רמז לגבי האופן בו המנגנון פועל.

במילים אחרות- לא רק השורות החוזרות עצמן הן אקראיות, אלא גם מספר השורות החוזרות הוא אקראי..

מכיוון שבכל שליפה יחזרו שורות אחרות, יתכן מצב בו נרצה שאותן X שורות אקראיות יחזרו בכל פעם; למשל אם מריצים תהליך על מדגם מהטבלה, מדבּגים, מתקנים, ורוצים להריץ אותו שוב על אותו מדגם לביקורת; או אולי אם מבצעים Join של מדגם מהטבלה עם עצמו, ורוצים ששני המדגמים יהיו זהים כדי שהחיתוך לא יהיה ריק.

במקרה כזה נוכל להפעיל את השליפה עם האופרטור Repeatable ומספר אקראי כלשהו, ואז עבור אותו מספר אקראי יחזור תמיד אותו סט (לצורך ההדגמה אני מריץ אותה שליפה פעמיים עם המספר האקראי 230):

Select  *

From    Sales.Customer TableSample(20 Rows)

Repeatable(230);

clip_image008

כדאי להסתייג ולציין שהשימוש באופרטור TableSample מוגבל לטבלאות משתמש בלבד, ולא נוכל לפנות בעזרתו לטבלאות מערכת, פונקציות המחזירות טבלה וכו';

ובנוסף- פילטור התוצאות בעזרת Where יפעל על השליפה בדיעבד ולכן יחזרו כנראה פחות שורות ממה שציינו.

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

כתיבת תגובה

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