Posts Tagged: mysql


12
אוק' 09

חיפוש ערך שלא נמצא בטבלה (mysql)

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

לדוגמא ניקח טבלה א, בה יש רשימת אנשים, וטבלה ב בה יש אנשים שקיבלו אישור שהייה בארץ. איך שולפים את האנשים שלא קיבלו אישוור? נניח לרגע שאי אפשר להכניס לטבלה השניה רשימת לא מאושרים.

התשובה היא זו:

SELECT * FROM tbl1 LEFT JOIN tbl2 ON tbl1.personId = tbl2.personId WHERE ISNULL(tbl2.personId)

או במילים אחרות – שלוף את כל הנתונים מטבלה אחת המחוברת לשניה, כשבשניה הID הוא null.


27
פבר' 09

אופטימיזציה של שאילתה

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

אחרי בדיקה קצרה, הגעתי למסקנה שעומדות בפני שלוש אפשרויות:

  • השאילתה היתה מורכבת משאילתה ותת שאילתה. תת השאילתה החזירה בנתונים הנוכחיים בין 0 ל200-300 תוצאות, ששאילתת האב לקחה מתוכן מידע. האופציה הראשונה אם כך, היתה לפרק את תת השאילתה לבקשה בזכות עצמה, לעבד את הנתונים, ולשלוח לשאילתה הראשונה. היתרונות: עיובד הנתונים אפשר עוד אופטימיזציה לוגית, וקריאות נפרדות לmysql איפשרו פחות זמן של נעילה של טבלאות. החסרונות: שתי קריאות לתוך הדאטהבייס עולות יותר זמן, והשיפור הסופי אינו גדול כל כך, בסה"כ, רק מפוצל.
  • הקמת memcache או שירות דומה (שכבר קיים במערכת) לשמירה של תוצאות מגבול מסויים, או פופלריות במיוחד, עם או בלי השיפור בנקודה הקודמת, ושימוש בהם ישירות מהזיכרון, ועדיין לסבול במידה זו או אחרת משאר השאילתות. היתרון: מהירות בשאילתות חביבות אשר נקראות יותר מהרגיל. החסרון: שימוש רב בזכרון יקר, לא ברור בכלל אם יש מבין השאילותות כאלה שנקראות פעמים רבות הרבה יותר מאחרות, וגם אם כן – הכמות של השאר שנקראות פעם או פעמיים כל אחת כל כך גדולה, שבסה"כ העומס על המערכת לא יורד.
  • שמירה של התוצאות, אפילו שמירה של הhtml שנוצר, בקובץ על הדיסק, אשר נמחק ברגעים חשובים או בטריגרים מסויימים, ובזמן אמת פשוט נקרא מהדיסק ללא פניה לדאטהבייס. היתרונות: מהיר, ללא שימוש בזיכרון, שיפור קריאות מוחלט לmysql. החיסרון: מקום על הדיסק, סיבוך במחיקה נכונה של המידע השמור, זמן גישה ארוך יחסית לדיסק.

מה אתם הייתם בוחרים? האם יש אפשרויות נוספות?