@WWW כתב בLIMIT עם מזהה שיחזור תמיד:
בצורה הזאת (=שכתבת), בכל טעינה נוספת של 60 ערכים, מתבצעת סתם שאילתה מיותרת
לדבריך אפשר לכאורה לבצע את הUNION רק בשאילתה ללא חיפוש (כלומר שזה יקרה רק בראשון, ואחרי כן לדאוג בJS שזה ישאר תמיד על הליין.
@WWW כתב בLIMIT עם מזהה שיחזור תמיד:
בצורה הזאת (=שכתבת), בכל טעינה נוספת של 60 ערכים, מתבצעת סתם שאילתה מיותרת
לדבריך אפשר לכאורה לבצע את הUNION רק בשאילתה ללא חיפוש (כלומר שזה יקרה רק בראשון, ואחרי כן לדאוג בJS שזה ישאר תמיד על הליין.
שלום וברכה
העניין הוא עם תיבת select אסינכרונית מול מידע מהשרת.
בערך בתיבה הוא מזהה, התווית היא labelל של המזהה ההוא.
הבעיה היא שבעת עליית התיבה הוא מושך מקס' 60 ואם המזהה לא קיים באפשרויות הוא יציג ערך NULL בתיבה.
חשבתי להכניס תמיד בתוך השאילתה את המזהה שכרגע הוא הערך, אך עדיין זה לא יעזור כי הוא לא יעקוף את ה60 של הLIMIT (במקרה והוא מאוחר יותר מבחינת הסדר.
התשובה היא: רק שני שאילתות?
@dovid תודה רבה, אעבור על זה מחר.
ואכן אני אמיר את זה לPHP.
שוב תודה
השאלה יותר בשביל לקבל עצה עם יש דרך טובה.
יש לי מערך של אובייקטים שמקורו מניתוח משפט SQL
לכל אובייקט יש את ערך הexpr
שמכיל את הטקסט
אני צריך למצוא קבוצות סוגריים בתוך ערכי הwhere
השאילתה הגולמית היא (לדוגמא):
WHERE a > b AND (a = 100 OR b < 3 OR (z > 10 AND y < 5))
כשאני מגיע בלולאה שלי לexpr
כזה שמתחיל בסוגריים (פותח) אני צריך למצוא את האינדקס של ההוא שסוגר אותו (שהמשפט בexpr
מסתיים עם סוגר).
בשים לב על שיש סוגרים מקוננים.
השאילתה הבאה:
SELECT `projects`.`id` AS `id`,
`projects`.`name` AS `Name`,
`projects`.`address` AS `Address`,
`customers`.`name` AS `Customer Name`,
COUNT(DISTINCT `steps`.`id`) AS `steps`,
SUM(`incomes`.`amount`) AS `total incomes`,
SUM(`expenses`.`amount`) AS `total expenses`
FROM `projects`
INNER JOIN `customers` ON `customers`.`id` = `projects`.`customer_id`
LEFT JOIN `incomes` ON `incomes`.`project_id` = `projects`.`id`
LEFT JOIN `steps` ON `steps`.`project_id` = `projects`.`id`
LEFT JOIN `expenses` ON `expenses`.`step_id` = `steps`.`id`
GROUP BY `projects`.`id`,
ORDER BY `id` ASC
LIMIT 10 OFFSET 0
לפרויקט אחד (לדוגמא) יש כמה הכנסות (4) וכמה הוצאות (5+) (שים לב שההוצאות מתייחסות לשלב ואילו ההכנסות מתייחסות ישירות לפרויקט)
מה שקורה בפועל שהסיכום של ההוצאות הוא כמות ההכנסות * סכום ההוצאות.
יש פיתרון לזה בJOIN פשוט או שחייבים ליצור שאילתת משנה?
@dovid אמר בתרגיל מתמטי של הסתרת מזהה רץ:
יש לך עצה קונקרטית עבורי או עבור מישהו אחר איך למנוע את זה להבא?
או שאתה רק מצהיר הצהרה רבת תועלת.
ראשית, אני לא מתכוון לא אליך באופן ספציפי ולא לאדם אחר בדווקא.
אבל אני חושב שחכמינו ז"ל ידעו והצהירו "דברי חכמים בנחת נשמעים".
נכון, לא כתוב שם "נכתבים" אבל אפשר לנסות לקחת את הרעיון גם אל הכתב.
כשאני מגיע לכזה שרשור אני נזכר בעצמי, כשאני לא מבין או יודע בדבר מסויים, אבל רק חשבתי שהבנתי את התשובה, או טעיתי בהגדרת השאלה והייתי בטוח שאני כן מבין בזה, הייתי מצפה לתגובה ברוח טובה.
זה באמת מרגיז כשהעונה לא ירד לסוף דעתך או שחשב להחכים אותי במה שכבר ידעתי ולא שאלתי... וגם השואל לפעמים מרגיש שאולי נראה שלא למד מילה או שנים בתחום מסוים וכבר שואל עליה, ובכל זאת הרבה דרכים לתגובה...
(ושלא תחשוב שאני מדבר רק על אחרים, אני זוכר את עצמי לפעמים שגם עונה ככה, אבל כשאני רואה אותי במראה - זו צביטה, מותר וצריך להשתנות)
סליחה על סטיה מהנושא (פשוט ביקשת... )
א גוטען ערב שבת!
@chv אמר בתרגיל מתמטי של הסתרת מזהה רץ:
זה נשמע קצת כמו מתקפה - כי כל השרשור הזה מרגיש כמו קרב אחד גדול
הדבר היחיד שאני מסכים איתו בכל השרשור הזה.
(לא להתקיף... אני פשוט עדיין לא מבין במעבדים וזכרונות וביצועים וכו וכו', ולכן אני מעדיף שלא להביע דעה בנושאים שאין לי בהם שמץ הבנה, אולי... אולי עוד יהיה לי חופש.. איזה בין הזמנים כזה... כדי ללמוד עוד משהו)
@aaron ניסיתי.
זה לא מתחיל להיות הsinglestorge
ראשית הביצוע כמעט שווה לmysql
שנית המעבר כואב הרבה יותר... (סוגי נתונים לא ניתנים להשוואה, ועוד כל מיני זבובים מעצבנים)
תגובה: SQL שאילתה תקועה... מה כן אפשר?
בהמשך לדיון לעיל
נפל לידי קישור לSinglestore
כמו הרבה דברים, אני חייב למשש אותם...
הורדתי למחשב עם דוקר העמסתי עליו את הDB*
וניסיתי את השאילתה שאיתה פתחתי את הדיון לעיל
לנגד עיני נעשה הפלא... כ 950ms ויש תגובה.
מה שמעניין שפעם שני של אותה השאילתה חוזר אחרי כ 80ms
עוד כמה ניסיונות וראיתי שזה שווה משהו...
שאילתה כמו זאת:
select
`records`.`id`,
price.price as price,
price.cost as cost,
incomens.amount as incomens,
price.price - price.cost as total,
projects.`count` as projects,
incomens.max as max_incomens,
price.price - incomens.amount as balanse
from
`records`
left join (
select
CAST(`meta_records`.`value` AS UNSIGNED) as join_id,
sum(`data3`.`value`) as price,
sum(`data4`.`value`) as cost
from
`meta_records`
INNER JOIN `meta_records` as `data2` on `data2`.`value` = `meta_records`.`record_id`
INNER JOIN `meta_records` as `data3` on `data2`.`record_id` = `data3`.`record_id`
INNER JOIN `meta_records` as `data4` on `data2`.`record_id` = `data4`.`record_id`
WHERE `meta_records`.`field_id` = 5
and `meta_records`.`field_type` = "App\\Models\\Field"
and `data2`.`field_id` = 7
and `data2`.`field_type` = "App\\Models\\Field"
and `data3`.`field_id` = 10
and `data3`.`field_type` = "App\\Models\\Field"
and `data4`.`field_id` = 11
and `data4`.`field_type` = "App\\Models\\Field"
GROUP BY `meta_records`.`value`
) as price on price.join_id = records.id
left join (
select
CAST(`meta_records`.`value` AS UNSIGNED) as join_id,
sum(`data3`.`value`) as amount,
max(CAST(`data3`.`value` AS DECIMAL)) AS `max`
from
`meta_records`
INNER JOIN `meta_records` as `data2` on `data2`.`value` = `meta_records`.`record_id`
INNER JOIN `meta_records` as `data3` on `data2`.`record_id` = `data3`.`record_id`
WHERE `meta_records`.`field_id` = 5
and `meta_records`.`field_type` = "App\\Models\\Field"
and `data2`.`field_id` = 12
and `data2`.`field_type` = "App\\Models\\Field"
and `data3`.`field_id` = 14
and `data3`.`field_type` = "App\\Models\\Field"
GROUP BY `meta_records`.`value`
) as incomens on incomens.join_id = records.id
left join (
select
CAST(`meta_records`.`value` AS UNSIGNED) as join_id,
count(*) as `count`
from
`meta_records`
WHERE `meta_records`.`field_id` = 5
and `meta_records`.`field_type` = "App\\Models\\Field"
GROUP BY `meta_records`.`value`
) as projects on projects.join_id = records.id
WHERE records.collection_id = 2
order by records.id
LIMIT 1000
בmysql: כ 600ms
בsimglestorge: כ 230ms (ובפעם השניה ואילך 120ms)
מצד אחד אין בו מפתח זר ואימות נתון מלבד הסוג, גם אי אפשר ליצור כמה עמודת בunique אחד, ואולי עוד אי אלו חסרונות.
אבל מן הצד השני הוא מהיר בהרבה כאמור.
גם ראיתי שאפשר במשפט WHERE להשתמש בשמות העמודות (אין צורך בhaving)
מישהו מכיר?
יש מה להגיד על זה?
@clickone אמר בSQL שאילתה תקועה... מה כן אפשר?:
(בעיקר אם יש בmeta_records הרבה רשומות)
אכן בטבלה זו יש מיליוני שורות
@clickone אמר בSQL שאילתה תקועה... מה כן אפשר?:
לשים אינדקס בטבלה meta_records על השדות שאתה מפלטר, עדיף אינדקס אחד על כל 3 השדות ביחד.
כמה זה יכול להפריע בעת הכנסה או מחיקת שורה?
@clickone אמר בSQL שאילתה תקועה... מה כן אפשר?:
אם אתה מסנן בטבלת המשנה משהו קבוע, אז להוסיף עמודה בטבלה הראשית שתכיל כן/לא, ופשוט לעדכן את זה בשעת ההכנסה של הנתונים.
אני מדגיש שהשיטה הזו לא נכונה מבחינת תיכנון נכון של DB (אחת הסיבות כי אתה יכול לחשב את זה, ואסור עקרונית לשמור נתון סטטי כשאתה יכול לחשב אותו), אבל במקרה של בעית ביצועים כזו אני אישית מאד בעד לשמור גם את הנתון סטטי ברשומה עצמה, ולא לחשב אותה כל פעם מחדש.
זה בדיוק מה שאני עושה, כאן מדובר בשלב שהוא אוסף את הנתון הצבירתי ע"מ לאחסן אותו כערך מטה לשורה המקורית.
@clickone אמר בSQL שאילתה תקועה... מה כן אפשר?:
אפשרות נוספת ששווה לבדוק (לא בטוח שזה אפשרי, אבל תנסה), זה לא לשים את החיפוש של הטבלה השניה כשאילתת משנה, אלא לחבר אותה כJOIN, ואז לסנן את כל מה שמתאים (ממילא אתה מחפש את מה שקיים ולא מה שחסר, כך שלכאורה ייתכן שאתה יכול להשתמש אפילו בINNER JOIN בלב שלם)
נוסה, חזר אחרי 300ms
השאילתה הבאה נתקעת לדקות ארוכות ללא מתן תשובה.
select
`records`.*,
`data0`.`value` as `laravel_through_key`
from
`records`
inner join `meta_records` as `data2` on `data2`.`record_id` = `records`.`id`
inner join `meta_records` as `data1` on `data1`.`record_id` = `data2`.`value`
inner join `meta_records` as `data0` on `data0`.`record_id` = `data1`.`value`
where
(
`data0`.`field_id` = 5
and `data0`.`field_type` = 'App\\Models\\Field'
)
and (
`data1`.`field_id` = 7
and `data1`.`field_type` = 'App\\Models\\Field'
)
and (
`data2`.`field_id` = 16
and `data2`.`field_type` = 'App\\Models\\Field'
)
and (
(
exists (
select
*
from
`meta_records` as `meta_exists`
where
`meta_exists`.`field_id` = 10
and `meta_exists`.`value` > 1000
and `meta_exists`.`record_id` = `data1`.`record_id`
)
)
)
and `data0`.`value` in (
4017,
4018,
4019,
4020,
4021,
4022,
4023,
4024,
4025,
4026,
4027,
4028,
4029,
4030,
4031,
4032,
4033,
4034,
4035,
4036,
4037,
4038,
4039,
4040,
4041,
4042,
4043,
4044,
4045,
4046,
4047,
4048,
4049,
4050,
4051,
4052,
4053,
4054,
4055,
4056,
4057,
4058,
4059,
4060,
4061,
4062,
4063,
4064,
4065,
4066,
4067,
4068,
4069,
4070,
4071,
4072,
4073,
4074,
4075,
4076,
4077,
4078,
4079,
4080,
4081,
4082,
4083,
4084,
4085,
4086,
4087,
4088,
4089,
4090,
4091,
4092,
4093,
4094,
4095,
4096,
4097,
4098,
4099,
4100,
4101,
4102,
4103,
4104,
4105,
4106,
4107,
4108,
4109,
4110,
4111,
4112,
4113,
4114,
4115,
4116
)
ללא הקטע הבא (מתוך השאילתה הקודמת):
and (
(
exists (
select
*
from
`meta_records` as `meta_exists`
where
`meta_exists`.`field_id` = 10
and `meta_exists`.`value` > 1000
and `meta_exists`.`record_id` = `data1`.`record_id`
)
)
)
השאילתה חוזרת תוך 230ms עם 823 תוצאות.
מה הדרך לנטרל את הכלב השחור??? או יותר נכון מה כך כף מציק לו שהוא נתקע...?
@dovid צודק, זה אכן לא יעיל סתם לעבד את המחרוזת של הלקוח.
יותר נכון לעדכן אותו על שגיאה ויסדר את זה לבד.
תודה רבה.
אני מקבל מהלקוח מחרוזת בא נאמר
1550.50*220.57+(2455)
ובעצם אני רוצה לבדוק/לנקות את המחרוזת בהתאם לתווים המותרים, ביניהם גם מילים (פונקציות) מותרות.
רשימת התווים והמילים כאן: https://github.com/chriskonnertz/string-calc#list-of-symbols
@yossiz אמר בubuntu כשרת מקומי:
תבדוק ש-mysqld מאזין על ה-IP של המחשב או 0.0.0.0 ולא על localhost
איך? ואיך אפשר להגדיר את זה?
@yossiz אמר בubuntu כשרת מקומי:
לבדוק שפורט 3306 לא סגור למחשב זה על ידי חומת אש
אשמח לקבל הדרכונת איך אבדוק?
נ.ב. ufw בסטטוס "לא פעיל"
בעבודתי נתקלתי לא מעט על דברים שלא ניתן (או ניתן באופן מסובך) לעשות על ווינדוס
לכן החלטתי להתחיל לעבוד על ubuntu עם RDP לווינודס
המחשבים שניהם ברשת אחת כמובן.
עכשיו אני רוצה לחבר את tableplus בווינדוס לnysql בubuntu
איך?
אם המחשב ברשת הוא 10.0.0.2
לא היה מספיק לספק את הIP והפורט (3306)?
יצרתי משתמש כך:
CREATE USER 'my'@'localhost' IDENTIFIED BY 'mysql';
GRANT ALL PRIVILEGES ON *.* TO 'my'@'localhost' WITH GRANT OPTION;
וכמובן (כמו כמעט תמיד) זה לא עובד.
מה עוד ניתן לפעול?
אני יכול אולי להבין שאני לא נמצא בlocalhost ולכן הבלגן מתחיל.
אמנם, איך אני יוצר משתמש שיתאים לגלובל המקומי גם במחשבים אחרים
מצאתי את הבעיה
כנראה שלא התקנתי טוב את תעודת האבטחה של נטפרי
@dotnet תודה על ההתייחסות
שלום וברכה
התקנתי bubunt עם GUI
ומשום מה apt update לוקח המון זמן... (כבר כמעט שעה ורק ב20%)
בדקתי את השרת ממנו הוא מקבל את הקבצים והוא כאן מישראל, כך שהמרחק לא העניין.
אשמח אם משהו נתקל בכגון דא או יוכל ליעץ לי מה לעשות
@yossiz אמר במה יותר טוב? DB:
אם היית משתמש ב-API של וורדפרס לכאורה היית מקבל מן המוכן פונקציה שעושה שאילתה ממוטבת הדק היטב
לא מכיר בAPI של וורדפרס אפשרות יחסים בין פוסט לפוסט ברמת המטא נתונים
@yossiz אמר במה יותר טוב? DB:
אבל עדיין נראה לי שאפשר למטב מאוד את השאילתה שם באמצעות תת-שאילתה יחידה שמביאה את כל המטא דאטה בבת אחת
ממש מעניין אותי, איך?