מיליוני מילים - mysql?

מיליוני מילים - mysql?

אני כותב כלי לאתר אינטרנט שבתגובה "לערך" שהכניס המשתמש מחזיר כמה מילים מתאימות מתוך מאגר של כ-70 מיליון מילים.

דבר ראשון, MYSQL יכול להתמודד עם מאגר של 70 מיליון מילים?

אם יהיה אינדקס על השדה של המילים, כמה זמן יקח ל-MYSQL למצוא את המילים המתאימות? האם זה משהו שיכול לקחת יותר מ-3 שניות על שרת אינטרנט סטנדרטי (512M, 1 Core)?

במידה ולא, מה האופציות שלי לעבודה עם מאגר כזה עם PHP?
 

pitoach

New member
בוא ננסה לעבור על הנקודות

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

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

>> כמה זמן יקח ל-MYSQL למצוא את המילים המתאימות?
תלוי בהרבה מאוד גורמים, החל במה קורה מחוץ לשרת (השרת לא פועל לבד אלא תחת חומרה מסויימת, תחת מערכת הפעלה, וביחד עם יישומים רבים אחרים), מה קורה בשרת מחוץ לטבלה בתוך השרת, ועד למה קורה עם הנתונים עצמם בטבלה (כמו אינדוס נכון, אופן העבודה ע הנתונים בזמן הכנסה , עדכון בחירה ועוד). לכן זו תשוה שאי אפשר ענות עליה.

>> שרת אינטרנט סטנדרטי (512M, 1 Core)
אתה רציני?!? זה אפילו לא מחשב נייד שמוכרים באתר יד שתיים ב20 שקלים! זה בקושי מספיק זכרון למערכת ההפעלה ממוצעת בשוק. כיצד הגעת למסקנה שזה שרת סטנדרטי?!? למחשב האישי שבו אתה מקליד כרגע בטח יש הרבה יותר משאבים. מה שאתה מציג זה בערך מקביל למשאבים של שרת לפני 25 שנים. זה מתאים למכונה וירטואלית הכי קטנה שפותחים היום בכמה בחינם. אפילו למכונה וירטואלית קטנה לא הייתי מתחיל בלי 1 גיגה זכרון לכל הפחות רק בשביל להבטיח זכרון שמכערכת ההפעלה צריכה ובלי לבר עדיין על מה שפעילות אפליקציות מיוחדות צריכות.
--> הזכרון המומלץ למערכת הפעלה ישנה כמו Windows Server 2008 הוא 2 גיגה או יותר. http://technet.microsoft.com/en-us/windowsserver/bb414778.aspx

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

** אני ממליץ לך לחפש חומר על FULL TEXT SEARCH אם אתה מתכוון לבצע חיפוש במילים.
*** תבדוק כמה מקום תופסות כל המילים. יכול להיות שתגלה ש 700 מילים של 7 תווים בממוצע תופס פחות מ 700 מגה בייט, ואם זה כל מה שאתה צריך בשביל האפליקציה אז אולי יותר מתאים לך להעלות את כל המילים לזכרון ולקבל מהירות הרבה יותר גדולה. תחשוב על תכנון האפליקציה ולא רק על תחילת עבודה כמה שיותר מהר.
**** לפני שאתה מתחיל להשקיע בפיתוח תבצע בדיקה על מה שמעניין אותך בכמה דקות. פשוט תיצור מצב זהה למה שאתה מדבר עליו ותבדוק בפועל על השרת שלך.
>> דרך אגב יש לי פונקציה שכתבתי פעם שבערתה אני מכניס כמויות כאלה והרבה יותר של שרשראות רנדומליות לצורך בדיקות בדיוק כאלה. פרסמתי גם את המאמר הבאים אבל הם יעזו רק בשתי SQL SERVER

T-SQL: Random String
http://social.technet.microsoft.com/wiki/contents/articles/21196.t-sql-random-string.aspx
SQL Server: Create Random String Using CLR
http://social.technet.microsoft.com...ql-server-create-random-string-using-clr.aspx
 

pitoach

New member
תיקוני הקלדה מהירה

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

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

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

>> שרת אינטרנט סטנדרטי (512M, 1 Core)
אתה רציני?!? זה אפילו לא מחשב נייד שמוכרים באתר יד שתיים ב 20 שקלים! זה בקושי מספיק זיכרון למערכת הפעלה ממוצעת בשוק.
כיצד הגעת למסקנה שזה שרת סטנדרטי?!?
למחשב האישי שבו אתה מקליד כרגע בטח יש הרבה יותר משאבים. המחשב האישי שלך נועד לתת שימוש למשתמש בודד. שרת נועד לתת שירות לאפליקציות ומשתמשים, אז אתה מוכן להשקיע על המחשב של הילד יותר משרת לעסק?!?
מה שאתה מציג זה בערך מקביל למשאבים של שרת לפני 20 שנים. זה מתאים למכונה וירטואלית הכי קטנה שפותחים היום בחינם. אפילו למכונה וירטואלית קטנה לא הייתי מתחיל בלי 1 גיגה זיכרון לכל הפחות רק בשביל שמערכת ההפעלה תפעל בשקט, ובלי לדבר עדיין על מה שאפליקציות שרצות עליה צריכות (לשרת שמחזיק אתר אינטרנט קטן פרטי בלי פעילות מיוחדת, הכולל שרת מסדי נתונים mysql או SQL EXPRESS, אחד גיגה אמור להספיק בקלות).
--> הזיכרון המומלץ רק בשביל מערכת הפעלה ישנה מאוד כמו Windows Server 2008 הוא 2 גיגה או יותר.
http://technet.microsoft.com/en-us/windowsserver/bb414778.aspx

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

ועתה לנקודות כלליות:
** אני ממליץ לך לחפש חומר על FULL TEXT SEARCH אם אתה מתכוון לבצע חיפוש במילים.
*** תבדוק כמה מקום תופסות כל המילים. יכול להיות שתגלה ש 700 מילים של 7 תווים בממוצע תופס פחות מ 700 מגה בייט, ואם זה כל מה שאתה צריך בשביל האפליקציה אז אולי יותר מתאים לך להעלות את כל המילים לזיכרון ולקבל מהירות הרבה יותר גדולה. תחשוב על תכנון האפליקציה ולא רק על תחילת עבודה כמה שיותר מהר.
**** לפני שאתה מתחיל להשקיע בפיתוח תבצע בדיקה על מה שמעניין אותך בכמה דקות. פשוט תיצור מצב זהה למה שאתה מדבר עליו ותבדוק בפועל על השרת שלך.
>> דרך אגב יש לי פונקציה שכתבתי פעם ובעזרתה אני מכניס כמויות של נתונים של שרשראות רנדומליות (בקיצור טקסים רנדומליים) לצורך בדיקות בדיוק כאלה. פרסמתי גם את המאמרים הבאים אבל הם יעזרו רק בשתי SQL SERVER


T-SQL: Random String
http://social.technet.microsoft.com/wiki/contents/articles/21196.t-sql-random-string.aspx
SQL Server: Create Random String Using CLR
http://social.technet.microsoft.com...ql-server-create-random-string-using-clr.aspx
 
תודה רבה על התגובה המושקעת!


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

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


>> אתה רציני?!? כיצד הגעת למסקנה שזה שרת סטנדרטי?!?
אנחנו כנראה מדברים על מערכות מאוד שונות. רוב האתרים הקטנים באינטרנט שמאוכסנים על שרתי לינוקס, מאוחסנים עשרות אתרים על שרת בגדול הזה - והם עובדים בסדר...לא טסים, אבל בסדר

אני חושב שהמעבד של שרתים הוא סוג אחר לגמרי ממעבד של מחשבים רגילים. השרת הזה באמת חלש, אבל זה החוזק סטנדרטי לשרתים של אתרי אינטרנט.

בעקבות הערה שלך עשיתי בדיקה גם על המחשב האישי שלי (i5 8GB SSD) וגם על השרת "הקטנצ'יק" כדי לוודא שאני לא סתם הולך לפתח משהו שיצטרך מחשב על... וצירפתי להודעה תמונה עם התוצאה. כמובן שהמחשב הרבה יותר מהיר מהשרת, אבל גם השרת מתמודד יפה עם 30 אלף שאילתות בשישים שניות.
אני עדיין לא יודע איך זה התמודד עם חיפוש טקסט בתוך 70 מיליון רשומות. עדיין צריך לבצע את הבדיקה הזו.


>>> ממליץ לך לחפש חומר על FULL TEXT SEARCH
חיפשתי. באמת מעניין, אבל לא מתאים לפרוייקט הזה.

>>> תבדוק כמה מקום תופסות כל המילים
לא נראה לי ש-70 מיליון יעלה בזיכרון של 512M...
אני אפילו לא טורח לבדוק...

>> דרך אגב יש לי פונקציה שכתבתי
נראה נחמד, אבל לא מתאים ללינוקס


תודה רבה על ההשקעה!
 

pitoach

New member
בכיף
אני אנסה להבהיר את הנקודות שהעלת:

>> זה רק רשימה של מילים בלי שום נתון נוסף. נראה לי שדה אחד בכל שורה מספיק. אפילו בלי ID. רק להוסיף לזה אינדקס רגיל.

* באופן תיארוטי אם אי שימוש ב ID והשמות הן ייחודיים בכל מקרה אז אתה לא צריך את הטר ID

>> תה המלצת שאולי כדאי לחתוך את זה לכמה טבלאות. השאלה אם זה לא מיותר אם יש אינדקס?

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

70 מליון רשומות כתבתי ש MySQL אמור לטפל בזה להערכי למרות שמנסיון שלי זה כבר יורגש במהירות.

>> אחתוך את זה לפי האות הראשונה של המילה. טבלה למילים שמתחילים בא', טבלה למילים שמתחילים בב' וכו' - האם זה היה יותר מהיר מהכל בטבלה אחת אם יש אינדקס (שהוא למעשה כבר מסדר את זה לפי אלף בית, כך נראה לי)?

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

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

גם אינדקס מחיחיב קריה של נתונים. נתונים של האינדקס כמובן וככל שטבלה גולה יותר האינדקס גדול יותר. מהירות עבודה עם אינדקס נקבעת בדרך כלל ממספר הרמות שלו. בשרתי SQL למשל כל הנתונים נשמרי באלמנט שנקרא "דף". כל דף מכיל תמיד 8K נתונים. אין הבדל תיאורטית במהירות בין אינדקס של 7K לאינדקס של 1K אבל אם תיאלץ לקפוץ רמה לשימוש ב 12K אז יהיה עלייך לקרוא 2 פעולות IO במקום ר פעולה אחת. תחשוב על אינדקס כמו מבנה של עץ נתונים (אתה יכול לחפש בגוגל עץ נתונים)

ספציפית במקרה הנוכחי צריך לבדוק מה השימוש ומה המערכת שלך אבל אני לא מניח בניחוש ראשני שיהיה צורך בחלוקה

>> נחנו כנראה מדברים על מערכות מאוד שונות. רוב האתרים הקטנים באינטרנט שמאוכסנים על שרתי לינוקס, מאוחסנים עשרות אתרים על שרת בגדול הזה - והם עובדים בסדר...לא טסים, אבל בסדר

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

נחזור לשאלה: הסברתי מעל שמערכת מינימלית תהיה עם 1 גיגה מכיוון שדיב רתי על וינדוס ומערכת ההפעלה עצמה מחייבת מינימום של 500 מגה לשימוש שלה. מערכת סטנדרטית לאתר אינטר קטנים מאוד פרטיים היא כמו שכתבתי מעל: מכונה וירטואלית עם מינימום 1 גיגה.
במקרה של לינוקס אתה חוסך 500 מגה של מערכת ההפעלה ואכן 500 מגה היא הדרישה המינימלית למערכת שצריכה להחזיק אתרי אינטרנט ביתיים קטנים. שימוש בשת MYSQL מחייב עוד לפחות 500 מגה כדי לעבוד תקין ועדיף הרבה יותר אבל תץיארוטית כן הוא יעבוד עם פחות.

>> אני חושב שהמעבד של שרתים הוא סוג אחר לגמרי ממעבד של מחשבים רגילים. השרת הזה באמת חלש, אבל זה החוזק סטנדרטי לשרתים של אתרי אינטרנט.

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

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

עתה נחזור לעניין המעבד, במכונה וירטואלית המעבד וירטואלי וכן הזכרון. הגדרת המשאבים תלויה באופן ההגדרה של המכונה הוירטואלית. בדרך כלל עושים שימוש בזכרון שיתופי וכן במעבד שיתוי. מה שה אומר זה שאם יש לך מכונה עם 10 גיגה זכרון למשל אתה יכול להקים עליה 11 מערכות של מכונות וירטואליות עם 1 גיגה זכרון כל אחת. כיצד?!?

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

>> בעקבות הערה שלך עשיתי בדיקה גם על המחשב האישי שלי (i5 8GB SSD) וגם על השרת "הקטנצ'יק" כדי לוודא שאני לא סתם הולך לפתח משהו שיצטרך מחשב על... וצירפתי להודעה תמונה עם התוצאה. כמובן שהמחשב הרבה יותר מהיר מהשרת, אבל גם השרת מתמודד יפה עם 30 אלף שאילתות בשישים שניות.

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


>> אני אפילו לא טורח לבדוק...
אתה לא צריך לטרוח! זה מתמטיקה פשוטה שאתה חייב למוד לבצע באש או עם נייר אם אתה עובד בפיתוח או עם מסדי נתונים.
כל תו תופס מקום של בייט אחד או שתיים (תלוי בשפה איתה עובדים למשל ובקידוד). 70 מליון מילים כפול ממוצע של 10 אותיות למילה נותן 700 מליון תווים ולכן 700 מגה בייט בזכרון יכול להיות בערך הגודל שצריך אם אכן מדובר בבייט אחד לכל אות.

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

>> נראה נחמד, אבל לא מתאים ללינוקס
זה רק לשרתי SQL
ברור שלא מתאים לך

לסיכום: אני חושב שיש לך את הבסיס כרגע וכל מה שנשאר זה לבצע בדיקה ולקבל התרשמות איתי

* בטח יש כאן כמה עשרות טעויות הקלדה.. אין לי כוח לתקן
אני מקווה שההודעה קריאה...
 
למעלה