בשבוע האחרון שדרגתי את תוכנת MySQL Workbench לגירסתה האחרונה (5.2.36). מעבר לחידושים שהוכנסו לשם (הגרפיים, ותיקוני הבאגים), אפשר לשים לב בעיקר לנסיון להתקרב למראה הכללי של התוכנה המקבילה עבור SQL Server

הגירסא החדשה של המוצר הזה משפרת את היציבות והופכת את הכלי להרבה יותר פונקציונלי ונוח לשימוש.
המסך הראשי שבו כותבים ומריצים שאילתות SQL השתנה בצורה משמעותית. הדבר הראשון – ביטול ההבדל בין הטאבים למעלה (השאילתות) לטאבים למטה (התוצאות) שעבדו בצורה קצת מוזרה בגירסה הקודמת, בין השאר, הם מאפשרים עריכה של תוצאות של בקשות SQL (יותר מתוחכם מה"Edit 200 Rows" של SSMS או Edit של הגירסא הקודמת של MSW).
מסכי עריכת הטבלאות, שבגירסא הקודמת היו תיבות דו שיח, הפכו לטאבים בחלון הראשי, גם כן כמו SSMS. חבל שאין אפשרות להחזיר את המצב הקודם כשיש צורך כזה.
בכלל, החבר'ה של MySQL עושים בשנים האחרונות מאמצים רבים להפוך את הכלים שלהם יותר ידידותיים למשתמשים (לא רק מסך CLI שחור ומאיים), בדגש על משתמשי חלונות, לאחר שלפני כמה שנים הם גילו שלמרות התדמית של הקוד הפתוח,הרוב המוחלט של המשתמשים שלהם משתמשים בכלל בחלונות, אם לפיתוח ואם לסביבת ייצור.
היכולת להפיץ מידע לכמות גדולה של גולשים בזמן קצר הוכיחה את עצמה שוב השבוע כשלאורך אחר הצהריים והערב פורסמו בפורומים, באתר הקול היהודי (השופר של יצהר והסביבה), ובהמשך גם בערוץ 7 פרסומים על חשש להרס מאחזים בלילה שבין יום שני לשלישי.
סיוון רהב מאיר מערוץ 2 עשתה כתבה על פורום ארץ מולדת אצלנו בערוץ 7, ועל השימושיות של הכלים האלה כשדרוג ביכולת להפרעה לכוחות הגירוש בדרך להריסת עוד מאחז או לכל פעולה שלטונית אחרת.
מדי פעם ערוץ 7 מקבלים צווים לחשיפת כתובות IP של גולשים. עד היום, הצווים הללו העלו חרס בידם. במקרה אחד לפחות ה-IP היה שייך למוסד חינוכי עם עשרות ומאות מחשבים, ובשאר המקרים כנראה פשוט לא הייתה עילה פלילית (חוץ מטעם רע של כותב ההודעה, שבד"כ נמחקה דקות מספר אחר כך).
למען הסר ספק, אני לא מתומכיה של ההפגנה האלימה שהייתה בחטמ"ר אפרים (שם, על פי דיווחי הגולשים בפורומים, היה מי שהכין פלוגות מג"ב וטרקטור כדי להרוס מאחז) או הפגנות אלימות בכלל.
תוך כדי שיטוט ב-History של MySQLConnector לסביבת NET., נתקלתי בכלי הפשוט הבא בקוד פתוח עבור בדיקות ביצועים של רכיבי קוד.
נשמע מעניין.
http://code.google.com/p/slimtune/
ביום שלישי האחרון השתתפתי בערב מעניין (ישר כח למארגנים) שהיה במרכז המחקר והפיתוח של Microsoft בהרצליה.
אחת ההרצאות שם הייתה על כלי מעניין בשם HebMorph, שהוא תוסף ל-Lucene/Lucene.net עבור חיפושים מורפולוגיים בעברית.
לאחר ההרצאה שוחחתי קצרות עם איתמר, המרצה והמפתח, וסיפרתי לו שהכלי שלו נותן תוצאות מצויינות אבל הביצועים שלו בעייתיים.
איתמר חייך, אמר לא יכול להיות ואולי טעינו בכמה דברים ונתן כמה רעיונות. אחר כך כבר נכנסנו למצגת הבאה ולזו שאחריה (זו על ה-nodejs) שזה תחום שמסקרן אותי – ולא מהיום.
למחרת בבוקר התיישבתי במשרד והחלטתי לחקור את הנושא לעומקו.
בדיקה 1: שימוש בכלים המובנים של Lucene
השתמשתי במחשב לא מזהיר במיוחד. מכונה עם מעבד 4 ליבות, 4G זיכרון, דיסק קשיח SATA בסיסי.
המערכת מאפשרת לאנדקס בערך כ-1000 מסמכים בשניה (מאגר החדשות של ערוץ 7)
בדיקה 2: שימוש ב-HebMorph, שאר הקוד ללא שינוי.
100-150 מסמכים בשניה.
בדיקה 3: שימוש ב-SimpleAnalyzer, גם כן מהחבילה של איתמר.
950~ מסמכים בשניה
מעקב אחר מנהל המשימות מראה שהכלי הקטן שפיתחתי, הן על בסיס Lucene והן על בסיס HebMorph/SimpleAnalyzer סובל מ-2 בעיות ביצועים מרכזיות:
- ניצול של מעבד אחד בלבד (מתוך 4 ליבות)
- אי ניצול יעיל של זיכרון
עם בעיית הזיכרון התמודדתי ע"י פיצול למנות (LIMIT של MySQL) של התוכן שמגיע מבסיס הנתונים, ופקודות GC.Collect ששמתי פה ושם.
על הדרך, גיליתי שהאיטיות הזו גרמה גם ל-Paging שבתורו גרר עוד יותר איטיות. "חיתוך" כמויות הנתונים איתם עבדתי שיפרו את המצב פלאים.
בעיית ה-CPU הייתה מורכבת יותר. הבעיה היא ש-IndexWriter פשוט לא מאפשר עבודה במקביל על אותו אינדקס. אמנם זה עבד לי מצויין בעבר אבל זה לא נתמך ואי אפשר לדעת איזה צרות זה יעשה.
קצת חפירה ברשת וקצת השקעה בקוד, ופיתחתי בסוף את הפיתרון הבא:
Dim oMem1 As Indexer = New HebrewIndexer(100)
Dim oMem2 As Indexer = New HebrewIndexer(100)
Dim oMem3 As Indexer = New HebrewIndexer(100)
Dim count As Integer = a.Length / 3
' array indexer start, end
Dim t1 As New Tasks.Task(Sub() _IndexDocuments(a, 0, oMem1, 0, count - 1))
Dim t2 As New Tasks.Task(Sub() _IndexDocuments(a, 1, oMem2, count, count * 2 - 1))
Dim t3 As New Tasks.Task(Sub() _IndexDocuments(a, 2, oMem3, count * 2, a.Length - 1))
t1.Start() : t2.Start() : t3.Start()
Tasks.Task.WaitAll(New Tasks.Task() {t1, t2, t3})
Dim t4 As New Tasks.Task(Sub()
oMem1.Flush() : oMem2.Flush() : oMem3.Flush()
Indexer.AddIndex(oMem1.Directory)
Indexer.AddIndex(oMem2.Directory)
Indexer.AddIndex(oMem3.Directory)
oMem1.Directory.Dispose() : oMem2.Directory.Dispose() : oMem3.Directory.Dispose()
GC.Collect() ' אני לא חד-משמעי בקשר לצורך בפונקציה הזו
End Sub)
t4.Start()
(הוצאתי מפה הרבה שורות שלא קשורות לעניין, ומחלקות שבניתי שגם הן לא קשורות. וכן, אני יודע שיש שיטות חכמות יותר לכתוב את הקוד הזה)
הפונקציה AddIndex היא בעצם הפנייה לפונקציה AddIndexesNoOptimize' של IndexWriter
הרעיון שפיתחתי לאחר שעות ארוכות הוא לייצר שלושה אינדקסים זמניים, בזיכרון, להכניס לתוכם את התוכן בשלושה Threadים שונים, ואחר כך לשלב את האינדקסים המוכנים באינדקסים הראשיים.
מכיוון שגם גישה לבסיס נתונים לוקחת זמן, התהליך של מיזוג האינדקסים קורה ב-Task רביעי (t4), כשבינתיים האפליקציה ממשיכה לרוץ ולוקחת מבסיס הנתונים את המידע הנחוץ להכנסה הבאה.
יש עוד לא מעט עבודה שאפשר לעשות בשלב החיפוש (להבדיל משלב האינדוקס), אבל זה כבר לפעם אחרת.
בהצלחה!
הנה ב-Windows Server 2008 R2

ומסתבר שזה קיים גם ב-Windows 7.

גם זה קורה לפעמים.
מעשה (אמיתי) שהיה לפני מס' חודשים:
עוזי ברוך (מנהל מחלקת החדשות של ערוץ 7) מתקשר ומתלונן: העלתי מבזק, והוא לא פורסם בזמן. עוברים יומיים, ושוב אותה תלונה, ושוב ושוב ושוב מאנשי צוות שונים – חומרים עולים לאתר באיחור.
את המבזק הבא אני מבקש להעלות בעצמי. מעמדת הפיתוח. מקבל את הטקסט ב-Messenger, מעתיק, ומדביק מול עיניהם. עובד.
אבל החבר'ה בחדשות ממשיכים להתלונן. אני בינתיים נובר כמו משוגע בכל רכיבי המטמון במערכת ומוודא שהם נמחקים (flush) כשנצרך. שום דבר.
עוברים חודשיים בהם אני סובל מטלפונים והודעות מתלוננות, עד שמצאתי את הבעיה האמיתית:
באחד הערבים, עבדתי מהבית עם RDP על אחד המחשבים במשרד, ופתאום אני קולט שיש פער זמנים בין המחשב שלי למחשב המרוחק. חמש דקות נוספות של בדיקה העלו שפשוט השעון של ה-DC, ואיתו כל המחשבים במשרד - ממהר!
בהיעדר מנהל רשת, התחברתי לשרת המתאים, הגדרתי שם שרת NTP ובזה נגמר העניין. לו רק יכולתי לחסוך חודשיים של סבל.

בעבר כתבתי על הבעיה הלא מאוד לא נפוצה שנגרמת כאשר משום מה מתבצעת פעולת Flush לחלקים גדולים של ה-Cache.
מערכת שביום יום מתמודדת בהצלחה עם העומס ונותנת זמני תגובה מצויינים, מגמגמת ואף קורסת לדקות ארוכות בשעה שה-Cache עליו היא מתבססת או חלקים ממנו קרס.
לפני קצת פחות משנתיים כתבתי על פתרון פשוט שמטרתו הייתה למנוע הרצת אותה פעולה מאות אלפי פעמים עד שנכנס ל-Cache אחד העותקים לשימוש בפעמים הבאות.
הפיתרון עבד מאוד יפה כל עוד נמצאים באותו שרת, ובאותו Proccess של IIS. גם במקרים שלא, הפעולה צומצמה מאלפים של בקשות מקבילות לכמה עשרות, בתלות בהגדרות הרשת.
ובכל זאת רציתי לפתח פתרון אחר.
זה לא Lock מושלם ב-100%, ובכל זאת, עושה את העבודה ומאיץ משמעותית את זמני עליית האתר מחדש אחרי Recycle או אבדן של חלקים משמעותיים ב-Cache.
הקוד פשוט מאוד וההערות שבתוכו די מיותרות.
Public Shared Function GetFromCacheWithLock(Of T)(ByVal Name As String, ByVal Minutes As Integer, ByVal SecondsLock As Integer, ByVal Func As Func(Of T)) As T
Try
' אם מישהו אחר באמצע
While GetCache("MainFuncs.GetCache.Lock" & Name) = 1
' כל עוד הפעולה רצה, תחכה
Threading.Thread.Sleep(30)
End While
InsertCache("MainFuncs.GetCache.Lock" & Name, 1, New TimeSpan(0, 0, SecondsLock)) ' "נעל" את הפעולה
Return GetFromCache(Name, Minutes, Func)
Finally
RemoveCache("MainFuncs.GetCache.Lock" & Name) ' הסר נעילה
End Try
End Function
Public Shared Function GetFromCache(Of T)(ByVal Name As String, ByVal Minutes As Integer, ByVal Func As Func(Of T), Optional ByVal Priority As Web.Caching.CacheItemPriority = CacheItemPriority.Default) As T
Return GetFromCache(Of T)(Name, New System.TimeSpan(0, Minutes, 0), Func, Priority)
End Function
Public Shared Function GetFromCache(Of T)(ByVal Name As String, ByVal Span As TimeSpan, ByVal Func As Func(Of T), Optional ByVal Priority As Web.Caching.CacheItemPriority = CacheItemPriority.Default) As T
Dim s As T
Dim z As Object = MemCacheClient.Get(Name)
If z Is Nothing Then ' אם אין במטמון, להריץ את הפעולה
s = Func()
InsertCache(Name, s, Span)
Return s
Else
Return z
End If
End Function
בהצלחה !
סוד גלוי הוא שהדפדפנים למכשירים ניידים (וזה כולל את Safari/Chrome למכשירי iOS ו-Android), את דפדפני Opera למינהם ולמיטב ידיעתי – גם IE9 הנייד.
זו גם הסיבה לאכזבתו של אחד מכתבי ערוץ 7 שרכש לעצמו iPad כמיני נייד (חרף אזהרותיי, אגב – אני המלצתי על PC) וגילה לאכזבתו שבמכשיר המדליק עריכת כתבות עליו היא עניין לא נוח במיוחד וגם מוגבל.
הערב נחשפתי במקרה ליציאתו לשוק של הדפדפן החדש של Firefox לניידים, שמבוסס על Firefox 4. חיפוש קצר נוסף העלה כי הדפדפן לנייד אכן תומך ב-contentEditable, וממילא עורכי טקסט המבוססים עליו יעבדו.
חידוש מרענן.
הבלוג המקורי שבדק את זה:
http://ckon.wordpress.com/2011/03/29/firefox-4-mobile-wysiwyg-contenteditable-designmode/
גירסאות קודמות של IE איפשרו לתוכנות המותקנות במחשב (הנפוצות שבהן: .NET Framework, אבל גם אחרים) לשנות את ה-User Agent שנשלח לשרת.
פרט לבעיית ביצועים זניחה (סתם עוד טקסט מיותר שנשלח עם כל בקשת HTTP), גילה כנראה מי שגילה את התכונה הזו כדרך "לבודד" משתמשים, לאור העובדה הפשוטה שכל מחשב הכיל User Agent מעט שונה.
ישר כח !
Default User-Agent (UA) String Changed
מדי כמה חודשים אני מפרסם פה את נתח השוק של הדפדפנים בישראל, כפי שנאגרו על ידי אתר האינטרנט של ערוץ 7. למיטב ידיעתי – אין עוד אתר אינטרנט גדול (שאינו טכני) ישראלי שמפרסם את הפרטים האלה.
הסטטיסטיקה של הנכנסים לבלוג הזה למשל, היא שונה בתכלית.
נתח שוק של דפדפנים:

נתח שוק של גירסאות IE:

נתח שוק של גירסאות Chrome:

נתח שוק של גירסאות Firefox:

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

אני חובב וותיק של Internet Explorer. כל הניסיונות השונים של חברים ומפתחים במהלך השנים לשכנע אותי לעבור לדפדפן אחר עלו בתוהו. בתור מפתח Web יצא לי לעבוד כמעט על כל דפדפן מאז IE4, כולל Netscape ז"ל (4 ו-6), Firefox עוד בתור Firebird, ועל לינוקס Konqueror וכשיצא ל-Windows גם Safari ובהמשך Chrome.
לכל אחד היו היתרונות והחסרונות שלו בתהליך הפיתוח (למשל Firebug) אבל כדפדפן גלישה משום מה היה ונשאר שם Avant Browser, שהוא בעצם מעטפת יפה ומוצלחת ל-IE.
מיד אחרי ששמעתי על יציאת גירסא RC1, מיהרתי להוריד ולהתקין אותה, ואלו הרשמים שלי:
1. חווייה - המערכת מהירה יותר בתחושה (גם בהשוואה ל-Chrome), יציבה משמעותית מהגרסה שקדמה לה ובאופן עקרוני – כיף לעבוד עליה.
יש עוד על מה לעבוד בגיזזרת הביצועים, אבל השיפור ניכר בהחלט, גם בצריכת הזיכרון של הדפדפן לאחר ימים ושבועות של עבודה.
בנוסף ניתן לראות שינויים בעיצוב ביחס לגרסת ה-Beta, והוספת פונקציות ברכיבים שונים של הדפדפן על פי בקשות של גולשים
אני מנחש שלכרטיס המסך יש השפעה ניכרת בנידון, אבל כרטיסי מסך נורמליים יש היום כמעט בכל מחשב.
Ctrl+Shift+L – "הדבק" כתובת/ביטוי לשורת הכתובת והיכנס אליה או חפש את הביטוי. שימושי להפליא. לא הצלחתי להבין מתי תתחלף הכתובת שבחלון ומתי הוא יפתח דווקא טאב חדש, אבל עדיין – נחמד.
Ctrl+Shift+N – העברת הטאב הפעיל לחלון חדש. שימושי לעיתים כשיש שני מסכים למחשב.
2. פיתוח – כלי הפיתוח של IE9 RC1 עובדים בצורה דומה לאלו שבגרסה שקדמה לו. חשוב לציין שיפור קטן (בתחושה!) בביצועים אולם מדובר עדיין בכלי איטי וכבד, בדומה ל-Firebug שהופך כל ריענון או שינוי בדף לאיטי מעט.
הטאב "רשת" שהתווסף מאפשר לעקוב אחרי הבקשות בדומה ל-Firebug ו-Chrome עושה עבודה יפה, על אף שאני בד"כ מעדיף את Fiddler עבור ניתוח בקשות HTTP לאור יכולותיו העדיפות.
3. באגים - אמנם מדובר בגירסת RC, אולם נתקלתי בבאגים מרכזיים במנוע ה-JS של הדפדפן, כאלו שאינם מאפשרים בכלל גלישה במס' לא מבוטל של אתרים (למשל CKEditor המוטמע באתר ערוץ 7 אינו פועל בכלל). מעבר למנוע IE8 עוקף את הבעיה אבל גם הופך את הדפדפן לאיטי יותר.
Geolocation לא הביא אותי לשום מקום (כולל לא למשרדי ספקית האינטרנט שלי). על הדרך גיליתי ש-"Bing" לא מכיל מפות בכלל באזור מגוריי או ביהודה ושומרון בכלל.
בגופן Arial העברי ניתן לראות לעיתים מיקום לא נכון של טקסט באנגלית בתוך טקסט בעברית – תמוה.
אין אפשרות לבטל את-Clear Type ואת המימוש שלו ב-IE9, טיפוסים כמוני שמעדיפים את הטקסט חד ולא מוחלק לא יכולים. גם השינוי המתאים בהגדרות לא עזר.
יש להם עוד הרבה עבודה לחבר'ה של IE, אבל זה נראה שהם בכיוון הנכון.
(הפוסט רלוונטי במידה מסויימת גם ל-SQL Server)
בעבר הדגמתי כיצד ניתן לבצע חלוקה לדפים ביעילות בMySQL וב-SQL Server, גם כשהטבלאות עליהן עובדים הולכות ומתנפחות.
נתקלתי לא אחת במקרה בו הגולש (או המקרה הנפוץ יותר – מנוע חיפוש), מתחיל לרוץ על הדפים ומגיע לדף ה-1000 ויותר.
במקרה כזה, מסד הנתונים צריך לעבור על כל הטבלה עד לשלב שאליו הוא הגיע. פעולה יקרה, איטית וזוללת משאבים
תרשו לי להציע פיתרון אחר.
ניקח לדוגמא את השליפה הזו:
- Source Query – slow on large LIMIT
select f_id, f_title, f_date from flashes where f_visible=1 order by f_date desc limit 10000,10
במערכת עמוסה, הפעולה הזו תיתקע. הפתרון המוצא הוא להוסיף אינדקס על השדות המתאימים (f_date, f_id), ולשלוף אותם בנפרד.
- Faster queries:
select f_id from flashes where f_visible=1 and f_date <= now() order by f_date desc limit 10000,10
ואחר כך
select f_id, f_title, f_date from flashes where f_id in (" & s & ") order by f_date desc
כש – s הוא פשוט רשימת מספרים מופרדים בפסיקים – 1,3,4,5,6.
ומה באשר ל-SQL Server – העניין לא שונה בהרבה. גם שם עניין ה-Covering Index מסייע משמעותית וניתן לעבוד באותה הצורה, גם בהיעדרו של LIMIT.
שימוש יעיל!
The solution: add a covering index on (f_date, f_id),
This make the first query to be fast, because it is Index-only opreation (and on a correct configuration – memory only). The second is simple just look on Primary Key, with the list of IDs from the first.
The variable "s" from the second query need to be the list of IDs with commas, like "1,2,56,8,4".
השבוע יצאה סוף סוף הגרסה הסופית של MySQL 5.5. אני מנחש שמשתמשי הלינוקס למיניהם ידושו בו ויחקרו אותו היטב, אבל חוץ מהם, מסתבר שהחבר'ה שם עשו עבודה טובה למדיי בכל מה שקשור למשתמשי מיקרוסופט.
1. ואת זה אני אומר מנסיון אישי, השיפור בביצועים בשליפות מתוחכמות מדהים! ואני מדבר בעיקר על המחשב השולחני שלי ולא על שרתי מפלצת.
2. השיפורים בביצועים על Windows מורגש היטב, לעיתים עד פי עשר משליפות קודמות. מישהו ב-Orcale לקח לראשונה ברצינות את מערכת ההפעלה הפופולרית ולא רק את Linux/Unix/Solaris.
3. MySQL הפכו את INNODB לברירת המחדל שלהם. בהתאמה, הוא גם מנצח את החבר הוותיק MyISAM בהרבה מאוד בדיקות ביצועים וגם בבדיקות הקטנות שאני ניסיתי לעשות.
מצד שני, היו כמה וכמה שליפות שנצרכתי לשנות ולשפץ
4. MySQL Connector לסביבת NET. התקדם לגירסא 6.3.5. השיפורים בביצועים וגם בשאר היכולות שלו – בהחלט נחמדים כשלומדים אותו לעומק.
שימוש מהנה!
ללא מילים.
יש עוד הרבה תרגומים הזויים של הודעות שגיאה ב-Framework. אולי כדאי להתחיל אוסף.
קיבלתי את המייל הזה הבוקר, ממשתמש שכנראה נפרצה התיבה שלו בחברת AT&T האמריקאית:
שלום
זה נותן לי תענוג גדול לכתוב לך הייתי הגלישה כאשר אני נתקל הפרופיל שלך ו משהו נגע בי ליצור איתך קשר אני אשמח מאוד להיות בקשר עם לך אם יהיה לך את הרצון איתי כדי שנוכל להכיר אחד את השני ולראות מה קרה future.i ישמח מאוד אם תוכל לכתוב לי דרך הדוא"ל שלי עבור לי לספר לך עוד על עצמי ולתת לך תמונה שלי בתור התחלה טובה. אני אהיה מחכה לשמוע ממך. שיהיה לך יום מבורך.
מתוך רחמים
קריאה קצרה של הטקסט מראה שהוא תורגם כנראה בשרותי גוגל או דומים להם. אם בעבר יכולתי פשוט לסנן מיילים שנכתבו באנגלית והיו ממקור לא מוכר, עכשיו זה יהיה קצת יותר מורכב. לא נורא
More Posts
Next page »