דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. MySql JOIN עם אינדקס לוקח המון זמן

MySql JOIN עם אינדקס לוקח המון זמן

מתוזמן נעוץ נעול הועבר תכנות
10 פוסטים 4 כותבים 336 צפיות 3 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • י מנותק
    י מנותק
    יוסף בן שמעון
    כתב ב נערך לאחרונה על ידי
    #1

    טבלת products

    id  INT, PRIMARY
    productId: VARCHAR, UNIQUE
    name: TEXT, NO INDEX
    

    טבלת products_users

    id  INT, PRIMARY
    userId: INT INDEX
    productId: VARCHAR, INDEX
    

    השאילתה:

    SELECT products_users.id, products_users.userId, products_users.productId, products.name AS name
    FROM products_users 
    JOIN products ON products.productId=products_users.productId
    WHERE userId=123
    

    שאילתה כזו לוקחת יותר מעשר שניות.
    אם אני מוריד את ה

    products.name AS name
    

    זה נגמר בפחות משניה, למרות שאני משאיר את ה JOIN!

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

    yossizY dovidD 2 תגובות תגובה אחרונה
    0
    • י יוסף בן שמעון

      טבלת products

      id  INT, PRIMARY
      productId: VARCHAR, UNIQUE
      name: TEXT, NO INDEX
      

      טבלת products_users

      id  INT, PRIMARY
      userId: INT INDEX
      productId: VARCHAR, INDEX
      

      השאילתה:

      SELECT products_users.id, products_users.userId, products_users.productId, products.name AS name
      FROM products_users 
      JOIN products ON products.productId=products_users.productId
      WHERE userId=123
      

      שאילתה כזו לוקחת יותר מעשר שניות.
      אם אני מוריד את ה

      products.name AS name
      

      זה נגמר בפחות משניה, למרות שאני משאיר את ה JOIN!

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

      yossizY מחובר
      yossizY מחובר
      yossiz
      כתב ב נערך לאחרונה על ידי
      #2

      @יוסף-בן-שמעון אתה יכול להביא פלט של EXPLAIN עבור שתי השאילתות?

      אגב, האם זה קורה על שרת לוקלי או מרוחק?

      📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

      י תגובה 1 תגובה אחרונה
      5
      • י יוסף בן שמעון

        טבלת products

        id  INT, PRIMARY
        productId: VARCHAR, UNIQUE
        name: TEXT, NO INDEX
        

        טבלת products_users

        id  INT, PRIMARY
        userId: INT INDEX
        productId: VARCHAR, INDEX
        

        השאילתה:

        SELECT products_users.id, products_users.userId, products_users.productId, products.name AS name
        FROM products_users 
        JOIN products ON products.productId=products_users.productId
        WHERE userId=123
        

        שאילתה כזו לוקחת יותר מעשר שניות.
        אם אני מוריד את ה

        products.name AS name
        

        זה נגמר בפחות משניה, למרות שאני משאיר את ה JOIN!

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

        dovidD מנותק
        dovidD מנותק
        dovid
        ניהול
        כתב ב נערך לאחרונה על ידי dovid
        #3

        @יוסף-בן-שמעון עצם העובדה שהכללת הname משנה היא צפויה ומובנת לגמרי.
        איך עובד אינדקס לא ראשי? יש טבלה נפרדת, בה מאוחסנים הערכים של האינדקס (productId) לפי סדר, וליד כל אחד יש מצביע למיקום בטבלה המקורית. איתור האינדקס הוא מאוד מהר (נניח חיפוש בינארי) אבל אחרי האיתור יש לנו ביד רק את ערך האינדקס עצמו שזה הproductId, בשביל לדעת את הname אנחנו צריכים לעקוב אחרי היעד בטבלת המקור.
        זה סיבת הבדל הזמן, ולכן נקודה זו לא עומדת במרכז השאלה. מרכז השאלה עובר לכמות הזמן - כמובן שזה לא אמור לקחת 10 שניות!
        עשר שניות לאיתור רשומה שיודעים את מיקומה זה להשערתי נובע מטבלה במצב לא מתוחזק (למשל אחרי מחיקה של הרבה שורות בכל מיני מקומות וכדומה) אולי פקודת OPTIMIZE לטבלה תשנה את המצב דרמטית.
        (בחזרה לנושא האינדקס לא ראשי, במידה והדוגמה היא אכן המציאות וכל מטרת האינדקס הוא תמיד תמיד להביא את השם, אפשר להורות לMYSQL לכלול בטבלת האינדקס ישירות את שדה הname.
        קוראים לזה covering index. במקרה כזה בעצם הMYSQL לא יפתח פיזית בכלל את טבלת המוצרים).

        • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
        • בכל נושא אפשר ליצור קשר dovid@tchumim.com
        י תגובה 1 תגובה אחרונה
        7
        • yossizY yossiz

          @יוסף-בן-שמעון אתה יכול להביא פלט של EXPLAIN עבור שתי השאילתות?

          אגב, האם זה קורה על שרת לוקלי או מרוחק?

          י מנותק
          י מנותק
          יוסף בן שמעון
          כתב ב נערך לאחרונה על ידי יוסף בן שמעון
          #4

          @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

          אתה יכול להביא פלט של EXPLAIN עבור שתי השאילתות?

          עם שליפה של העמודה הטקסטואלית:
          slow.png

          בלי שליפה
          quick.png
          זה אומר שבשאילתה האיטית הוא בכלל לא משתמש באינדקס?

          @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

          אגב, האם זה קורה על שרת לוקלי או מרוחק?

          גם וגם

          dovidD yossizY 2 תגובות תגובה אחרונה
          3
          • dovidD dovid

            @יוסף-בן-שמעון עצם העובדה שהכללת הname משנה היא צפויה ומובנת לגמרי.
            איך עובד אינדקס לא ראשי? יש טבלה נפרדת, בה מאוחסנים הערכים של האינדקס (productId) לפי סדר, וליד כל אחד יש מצביע למיקום בטבלה המקורית. איתור האינדקס הוא מאוד מהר (נניח חיפוש בינארי) אבל אחרי האיתור יש לנו ביד רק את ערך האינדקס עצמו שזה הproductId, בשביל לדעת את הname אנחנו צריכים לעקוב אחרי היעד בטבלת המקור.
            זה סיבת הבדל הזמן, ולכן נקודה זו לא עומדת במרכז השאלה. מרכז השאלה עובר לכמות הזמן - כמובן שזה לא אמור לקחת 10 שניות!
            עשר שניות לאיתור רשומה שיודעים את מיקומה זה להשערתי נובע מטבלה במצב לא מתוחזק (למשל אחרי מחיקה של הרבה שורות בכל מיני מקומות וכדומה) אולי פקודת OPTIMIZE לטבלה תשנה את המצב דרמטית.
            (בחזרה לנושא האינדקס לא ראשי, במידה והדוגמה היא אכן המציאות וכל מטרת האינדקס הוא תמיד תמיד להביא את השם, אפשר להורות לMYSQL לכלול בטבלת האינדקס ישירות את שדה הname.
            קוראים לזה covering index. במקרה כזה בעצם הMYSQL לא יפתח פיזית בכלל את טבלת המוצרים).

            י מנותק
            י מנותק
            יוסף בן שמעון
            כתב ב נערך לאחרונה על ידי
            #5

            @dovid כתב בMySql JOIN עם אינדקס לוקח המון זמן:

            למשל אחרי מחיקה של הרבה שורות בכל מיני מקומות וכדומה

            מה המשמעות של מחיקת שורות? למה זה מזיק לטבלה?

            תגובה 1 תגובה אחרונה
            0
            • י יוסף בן שמעון

              @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

              אתה יכול להביא פלט של EXPLAIN עבור שתי השאילתות?

              עם שליפה של העמודה הטקסטואלית:
              slow.png

              בלי שליפה
              quick.png
              זה אומר שבשאילתה האיטית הוא בכלל לא משתמש באינדקס?

              @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

              אגב, האם זה קורה על שרת לוקלי או מרוחק?

              גם וגם

              dovidD מנותק
              dovidD מנותק
              dovid
              ניהול
              כתב ב נערך לאחרונה על ידי
              #6

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

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

              • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
              • בכל נושא אפשר ליצור קשר dovid@tchumim.com
              תגובה 1 תגובה אחרונה
              4
              • י יוסף בן שמעון

                @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

                אתה יכול להביא פלט של EXPLAIN עבור שתי השאילתות?

                עם שליפה של העמודה הטקסטואלית:
                slow.png

                בלי שליפה
                quick.png
                זה אומר שבשאילתה האיטית הוא בכלל לא משתמש באינדקס?

                @yossiz כתב בMySql JOIN עם אינדקס לוקח המון זמן:

                אגב, האם זה קורה על שרת לוקלי או מרוחק?

                גם וגם

                yossizY מחובר
                yossizY מחובר
                yossiz
                כתב ב נערך לאחרונה על ידי yossiz
                #7

                @יוסף-בן-שמעון האם אתה יכול לעזור לי לעשות דוגמה לבעיה? כי עשיתי פידל ולא הצלחתי לקבל את התוכנית שאתה קיבלת

                https://www.db-fiddle.com/f/kCDQKugi9XWwtb5uKm1YRn/0

                📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                י תגובה 1 תגובה אחרונה
                3
                • yossizY yossiz

                  @יוסף-בן-שמעון האם אתה יכול לעזור לי לעשות דוגמה לבעיה? כי עשיתי פידל ולא הצלחתי לקבל את התוכנית שאתה קיבלת

                  https://www.db-fiddle.com/f/kCDQKugi9XWwtb5uKm1YRn/0

                  י מנותק
                  י מנותק
                  יוסף בן שמעון
                  כתב ב נערך לאחרונה על ידי
                  #8

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

                  (הזוי שאם אני מפריד את השאילתות, קודם שולף יוזרים ואחר כך מוצרים עם where in, ומאחד אותם בעצמי, זה לוקח בערך עשירית שניה, לעומת שאילתה מאוחדת שלוקחת בערך עשר שניות, עקוב mysql ואנוש מי ידענו...)

                  תגובה 1 תגובה אחרונה
                  7
                  • Aharon 0A מנותק
                    Aharon 0A מנותק
                    Aharon 0
                    כתב ב נערך לאחרונה על ידי Aharon 0
                    #9

                    אולי זה יעזור ?
                    [https://www.w3schools.com/sql/sql_create_index.asp]
                    (https://www.w3schools.com/sql/sql_create_index.asp)

                    dovidD תגובה 1 תגובה אחרונה
                    0
                    • Aharon 0A Aharon 0

                      אולי זה יעזור ?
                      [https://www.w3schools.com/sql/sql_create_index.asp]
                      (https://www.w3schools.com/sql/sql_create_index.asp)

                      dovidD מנותק
                      dovidD מנותק
                      dovid
                      ניהול
                      כתב ב נערך לאחרונה על ידי
                      #10

                      @Aharon-0 איך זה יעזור?

                      • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                      • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                      תגובה 1 תגובה אחרונה
                      2
                      תגובה
                      • תגובה כנושא
                      התחברו כדי לפרסם תגובה
                      • מהישן לחדש
                      • מהחדש לישן
                      • הכי הרבה הצבעות


                      בא תתחבר לדף היומי!
                      • התחברות

                      • אין לך חשבון עדיין? הרשמה

                      • התחברו או הירשמו כדי לחפש.
                      • פוסט ראשון
                        פוסט אחרון
                      0
                      • דף הבית
                      • קטגוריות
                      • פוסטים אחרונים
                      • משתמשים
                      • חיפוש
                      • חוקי הפורום