ההרצאה שלי "Introduction to Big Data and NoSQL solutions" זמינה ב-YouTube

http://www.youtube.com/watch?v=4dGzaOJRVag

 

ההרצאה ניתנה בפורום ISUG (ארגון משתמשי SQL Server בישראל) במיקרוסופט רעננה ב-9 באפריל 2013.

תגובות והערות יתקבלו בברכה.

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

קבצי ההדגמה מהרצאתי בשבוע אורקל: "Advanced PL/SQL: New features and Tips & Tricks For Better Performance"

קבצי ההדגמה מהרצאתי בשבוע אורקל: "Advanced PL/SQL: New features and Tips & Tricks For Better Performance" אפשר להוריד מהלינק במצורף:

קבצי ההדגמה מההרצאה

טבלאות זמניות לפעמים יכולות להיות מתכון לבעיות (ויצא לי חרוז)

טבלאות זמניות זה דבר נהדר. SQL Server מאפשר לבנות טבלאות זמניות לוקליות (בניגוד לאורקל שתומך רק טבלאות זמניות גלובליות- לפחות בגרסה 11g). אבל ה-scope של הטבלאות הזמניות יכול להיות מבלבל ולכן יש תמיד לתת לטבלאות זמניות שמות משמעותיים ולא משהו שרירותי כמו a#.

להלן דוגמה:

CREATE PROCEDURE a AS

CREATE TABLE #a (x INT);

      INSERT INTO #a VALUES (1);

      EXEC b;

      SELECT * FROM #a;

GO

CREATE PROCEDURE b AS

      CREATE TABLE #a (x INT);

      INSERT INTO #a VALUES (2);

      SELECT * FROM #a;

GO

בדוגמה הפרוצדורה b יוצרת טבלה זמנית שנקראת a# וזאת למרות שנוצרה כבר טבלה בשם a# בפרוצדורה שקוראת לה. אבל הטבלה a# בפרוצדורה b היא טבלה אחרת מאשר הטבלה a# שנוצרה לפני כן בפרוצדורה a.

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

ALTER PROCEDURE b AS

      –CREATE TABLE #a (x INT);

      INSERT INTO #a VALUES (2);

      SELECT * FROM #a;

GO

במקרה הזה פעולת ה-insert לטבלה a# שבפרוצדורה b היא לטבלה שנוצרה בפרוצדורה a. כלומר, הטבלה a# היא סוג של "משתנה גלובלי" ומוכרת גם בפרוצדורה היוצרת וגם בפרוצדורות שתחתיה (שנקראות ע"י הפרוצדורה היוצרת).

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

איך לדפדף עם SQL Server 2011

ב- SQL Server 2011 ישנה אופציה חביבה המפשטת מאד את פעולת ההבאה של קבוצת נתונים (או דף) מתוך כלל תוצאותיה של שאילתא. מדובר בביטוי חדש בשם OFFSET הבא כתוספת לאחר ביטוי Order by והמבנה שלו הוא זה:

 

<offset_fetch> ::=

{

OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }

[

FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression }

{ ROW | ROWS } ONLY

]

}

לדוגמה: נניח שאנו מחלקים את תוצאות השאילתה לדפים בגודל 10 שורות כ"א. אם נרצה לשלוף את הדף השני נבצע משהו כזה:

select *

from Production.Product

order by name asc

offset 10 rows

fetch first 10 rows only

 בדוגמה שלפנו מטבלת המוצרים את 10 המוצרים שבדף השני (מיון לפי שם המוצר), כלומר המוצרים במיקום 11 עד 20 ע"פ המיון שנבחר.

אין ספק שזה נוח להפליא. השאלה היא: האם SQL Server חכם מספיק כדי לשלוף את הדף הרצוי בצורה המהירה ביותר?

התשובה: שיחקתי עם זה קצת ובחנתי את ה-execution plans, ואכן ה-SQL Server יודע לשנות את ה-plan לפי ה-offset ולפי כמות הנתונים המבוקשת:

  • מספר הקריאות הלוגיות הוא אופטימלי (נשלפים רק הנתונים הדרושים).
  • נבחרים האינדקסים המתאימים לפי המיון. כלומר – אם יש אינדקס על שדה המיון (בדוגמה זה השדה name), אזי הנתונים עשויים להישלף בעזרת האינדקס (תלוי כמה נתונים אנו שולפים).

 

הפיצ'ר הזה לדעתי הוא פיצ'ר שישפר את הביצועים באופן אמיתי כשמדובר בשליפת "דפים" כשמשווים אותו לכל צורת דפדוף אחרת (לרוב בשימוש עם row_number() ועם שאילתא בתוך שאילתא).

אין ספק שזו תוספת נחמדה ומקורית (אני לא מכיר כזה פיצ'ר באורקל).



לפתוח דף חדש

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

יש למעשה שתי שיטות דפדוף עיקריות (ועוד אחת בהמשך):

  1. שרת האפליקציה קורא את כל הרשימה מה-DB אל מבנה בזיכרון (כמו DataSet בדוט נט) ומשם הוא מבצע rendering ל-HTML רק את המידע שיש להציג בדף.
  2. שרת האפליקציה מפעיל SQL על כל פעולת דפדוף ומביא מה-DB רק את המידע הרלוונטי שיש להציג בדף הנוכחי.

יתרונות וחסרונות

שיטה

יתרונות

חסרונות

1

מתבצעת קריאה בודדת לשרת ה-DB

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

2

כמות הזכרון הנצרכת בשרת האפליקציה היא קטנה (כגודל הפריטים בדף).

כל פעולת דפדוף יוצרת ביצוע שאילתא ב-DB

 

מדוע השיטה השניה עדיפה? בגלל הפסיכולוגיה של משתמשים באינטרנט. משתמשים לא אוהבים לדפדף יותר מדי. אם, למשל, נשלפו 10000 פרטים ומוצגים 20 פריטים בדף (כלומר נוצרים 500 דפים), אזי המשתמשים לרוב יסתכלו בדף הראשון והשני. הסיכוי שיבחרו להסתכל בדף מס' 392 הוא לרוב קלוש מאד. בגוגל יודעים זאת היטב ומנגנון שליפת תוצאות החיפוש בנוי כך שנקבל מהר את תוצאות החיפוש של הדפים הראשונים.

ישנה גם שיטה מס' 3 שהיא שילוב של שיטה 1 ו-2. בשיטה זו יוצרים "מגה דף" בזכרון, כלומר, מעלים ל-DataSet כמה דפים (כלומר סוג של cache). אם נשתמש בדוגמה שלעיל, נבנה "מגה דף" של 100 פריטים ("מגה דף" = 5 דפים). כשהמשתמש יבקש לראות את דף 2 (פריטים 21 עד 40) אז נציג את הפריטים מה-DataSet ולא נבצע קריאה נוספת ל-DB.

שיטה 3 – יתרונות וחסרונות

שיטה

יתרונות

חסרונות

3

הרבה פחות קריאות ל-DB מאשר בשיטה השניה וצריכת הזכרון בשרת האפליקציה קטנה בהרבה מבשיטה הראשונה.

מנגנון ה-Caching הזה (בדוגמה, 5 דפים), קצת יותר מורכב לפיתוח. צריך לדעת מתי לקרוא מה-DB ומתי לקרוא מה-cache.

 

רקוויאם ל-DTS

עכשיו זה סופי – אין יותר תמיכה ב-DTS בגרסת SQL Server 2011. אי אפשר להריץ אותם יותר והם אפילו לא בתפריט.

זוהי קריאה אחרונה למי שיש לו DTS-ים להמיר אותם ל-SSIS packages.

דרך אגב, מ-SSMS 2011 אי אפשר להריץ DTS גם אם מתחברים ל-instance בגרסה ישנה יותר (2000/2005/2008) – הוא פשוט לא קיים בתפריט.

האם יש למיקרוסופט ב- SQL Server 2011 תשובה ל-Oracle RAC?

האם יש למיקרוסופט ב- SQL Server 2011 תשובה ל-Oracle RAC?

אני אענה כמו נשיאנו שמעון פרס: "כן ולא".

ה-Oracle RAC הוא פתרון ותיק של אורקל שהוצג כבר די מזמן (מימי אורקל 9). ה-RAC החליף את ה- OPS או (Oracle Parallel Server) המיושן שהיה בנוי על הנעילות של מערכת ההפעלה (בניגוד ל-RAC שבו הנעילות מנוהלות ע"י האורקל ללא שימוש בשירותים של מערכת ההפעלה). במשפט אחד, ה-RAC (קיצור ל- Real Application Clustering) הוא פתרון המשלב גם זמינות גבוהה (כאשר שרת נופל, האחרים מגבים אותו) וגם פתרון scalability (יכולת להתמודד עם יותר משתמשים ועם עומס רב יותר ע"י הוספת עוד שרתים למערך שכולם אקטיביים). ה-RAC הוא פתרון נפלא והוא יחודי לאורקל (וגם אחת הסיבות מדוע אורקל היא המובילה העולמית בשוק). אבל מכיל כמה חסרונות כמו העובדה שהוא יקר להחריד וכמו גם המורכבות הרבה שלו הן בהתקנה ובעיקר בתחזוקה הדורשת מומחיות כדי להוציא מה-RAC  את הביצועים האופטימליים.

למיקרוסופט תמיד היו שני יתרונות בולטים מעל אורקל: המחיר (הזול יותר) והפשטות (או קלות/נוחות השימוש). והנה מיקרוסופט מציגה ב-SQL Server 2011 (המכונה Denali) פיצ'ר חדש מהניילונים המכונה AlwaysOn שהוא למעשה שכלול מנגנון ה-mirroring של המערכת שנועד להגדיל את הזמינות שלה.

אחת הבעיות של מנגנון ה-mirroring  הקיים בגרסאות הנוכחיות היא שכל DB מועתק לרפליקה שלו באופן בלתי תלוי ונפרד – וזו בעיה. בסיסי נתונים של SQL Server לרוב מכילים תלויות לוגיות של נתונים . ה- AlwaysOnמציע אפשרות לבנות Availability groups כשכל קבוצה מכילה מספר בסיסי נתונים. בזמן Failover אפשר לבצע Failover לכל הקבוצה ובכך להבטיח שהאפליקציה שמשתמשת במספר בסיסי נתונים תמשיך לעבוד עם ה- mirror.

חידוש נוסף של ה-AlwaysOn הוא היכולת להשתמש ברפליקה שלו – אבל… לקריאה בלבד (שלא כמו ב-Oracle RAC שמאפשר גם כתיבה תוך סנכרון נעילות בין השרתים). ב-SQL 2008 לא ניתן להשתמש ברפליקה כלל, אלא רק כשעושים failover. היכולת להשתמש ברפליקה לקריאה יכול להיות שימושי במיוחד לצורך הפקת דו"חות מנתוני אמת על גבי שרת הרפליקה מבלי להכביד או להשפיע על הביצועים של השרת העיקרי.

עוד חידוש הוא שאפשר לבנות עד 4 העתקים ל-DB (וזה נהדר במיוחד לצורך disaster recovery).

ה-AlwaysOn זקוק ל-Windows clustering שבלעדיו אי אפשר להשתמש בו. לשימחתנו אם פעם cluster  חייב אותנו למנגנון storage משותף ועשה בעיות אם החומרה של השרתים הייתה שונה, הרי שהיום (Windows Server 2008) המנגנון הזה בלתי תלוי ואפשר להחזיק שרת אחד של HP בת"א ושרת אחר של  Dell בניו יורק ואז לבצע mirroring  ביניהם. יש לשים לב לרשיון שמחייב Windows server Enterprise Edition כדי לתמוך ב-Clustering.

לסיכום: האם יש למיקרוסופט ב- SQL Server 2011 תשובה ל-Oracle RAC?

כן – מבחינת הזמינות.

לא – מבחינת ה-scalability.